当前位置: 代码网 > it编程>编程语言>Java > Spark(十六)Spark Core 调优之资源调优JVM的基本架构_spark jvm 内存组成

Spark(十六)Spark Core 调优之资源调优JVM的基本架构_spark jvm 内存组成

2024年08月04日 Java 我要评论
存储类信息、常量、静态变量等数据,是线程共享的区域,为与Java堆区分,方法区还有一个别名Non-Heap(非堆);:又分为java虚拟机栈和本地方法栈主要用于方法的执行。

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事it行业的老鸟或是对it行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

方法区:存储类信息、常量、静态变量等数据,是线程共享的区域,为与java堆区分,方法区还有一个别名non-heap(非堆);

:又分为java虚拟机栈和本地方法栈主要用于方法的执行。

1.2 如何通过参数来控制各区域的内存大小

在这里插入图片描述

1.3 控制参数

-xms设置堆的最小空间大小。

-xmx设置堆的最大空间大小。

-xx:newsize设置新生代最小空间大小。

-xx:maxnewsize设置新生代最大空间大小。

-xx:permsize设置永久代最小空间大小。

-xx:maxpermsize设置永久代最大空间大小。

-xss设置每个线程的堆栈大小。

没有直接设置老年代的参数,但是可以设置堆空间大小和新生代空间大小两个参数来间接控制。

老年代空间大小=堆空间大小-年轻代大空间大小

1.4 jvm和系统调用之间的关系

在这里插入图片描述
方法区和堆是所有线程共享的内存区域;而java栈、本地方法栈和程序员计数器是运行是线程私有的内存区域。

二、jvm各区域的作用

2.1 java堆(heap)

对于大多数应用来说,java堆(java heap)是java虚拟机所管理的内存中最大的一块。java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

java堆是垃圾收集器管理的主要区域,因此很多时候也被称做“gc堆”。如果从内存回收的角度看,由于现在收集器基本都是采用的分代收集算法,所以java堆中还可以细分为:新生代和老年代;再细致一点的有eden空间、from survivor空间、to survivor空间等。

根据java虚拟机规范的规定,java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样。在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-xmx和-xms控制)。

如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出outofmemoryerror异常。

2.2 方法区(method area)

方法区(method area)与java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做non-heap(非堆),目的应该是与java堆区分开来。

对于习惯在hotspot虚拟机上开发和部署程序的开发者来说,很多人愿意把方法区称为“永久代”(permanent generation),本质上两者并不等价,仅仅是因为hotspot虚拟机的设计团队选择把gc分代收集扩展至方法区,或者说使用永久代来实现方法区而已。

java虚拟机规范对这个区域的限制非常宽松,除了和java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。相对而言,垃圾收集行为在这个区域是比较少出现的,但并非数据进入了方法区就如永久代的名字一样“永久”存在了。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载,一般来说这个区域的回收“成绩”比较难以令人满意,尤其是类型的卸载,条件相当苛刻,但是这部分区域的回收确实是有必要的。

根据java虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出outofmemoryerror异常。

2.3 程序计数器(program counter register)

程序计数器(program counter register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

由于java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

如果线程正在执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是natvie方法,这个计数器值则为空(undefined)。

此内存区域是唯一一个在java虚拟机规范中没有规定任何outofmemoryerror情况的区域。

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

实战项目、大纲路线、讲解视频,并且后续会持续更新**

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com