java eden s1 s2 old_二、JVM堆内存分布及GC过程

51835ba5b2c0e56d49b455579991b636.png

1、内存分配与设置

堆内存分配

JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

非堆内存分配

JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

由Permanent Generation和Code Cache组成

Permanent Generation保存虚拟机自己的静态(refective)数据

主要存放加载的Class类级别静态对象如class本身,method,field等等,permanent generation空间不足会引发full GC

Code Cache 用于编译和保存本地代码(native code)的内存

JVM内部处理或优化 JVM内存限制(最大值)

JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然 可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统 下为2G-3G),而64bit以上的处理器就不会有限制了。

内存分布具体说明:

堆中new对象首先进入Eden区,当Eden区满了之后,会触发Young GC 判断Eden区中的对象是否还有指向其的引用,如果没有则被直接回收,如果还有引用指向则将其移入survivor1区;之后当Eden区再次满了时会触发第二次Young GC 判断Eden区中的对象是否还有指向其的引用,如果没有则被直接回收,如果还有引用指向则将其移入survivor2区,同时会判断survivor1区中对象是否还有指向其的引用,如果没有直接回收除,有将其移至survivor2区(第二次Young GC 的时候相当于回收说有无引用的对象同时 s1与s2位置互换);Young GC 循环奖Eden区的对象存入survivor区,而每执行一次age+1,JVM 默认age=15,当age=15之后出发Young GC时将其移入老年代,老年代不断的被移入数据,当老年区满了的时候 触发 full GC ,full GC将对整个堆进行GC,没有引用直接回收,有引用则移入持久代(1.8及以后没有永久代用元空间替代),full GC  不影响Young GC 也不影响对象age

2、内存申请过程

内存申请步骤:

JVM会试图为相关Java对象在Eden区初始化一块内存区域

Eden满足则划分内存,申请结束

Eden不满足则JVM试图释放在Eden区中所有的不活跃对象(YGC),释放后若Eden区空间仍然不足以放入新对象,则试图将部分Eden区中活跃的对象放入Survivor区(YGC)

Survivor区被用来作为Eden区及Old的中间交换区,当Survivor区空间足够时,Survivor区的部分对象(存活次数超过turning threshold)会被移到OLD区,否则会保留在Survivor区

当old区空间不够时,JVM会在old区进行(FGC)

完全垃圾收集后,若Survivor及old区仍然无法存放Eden复制过来的对象,导致JVM无法在Eden区为新对象创建内存区域,则出现 “Out of memory错误”

3、对象衰老过程

大部分新创建的对象的内存都分配自eden区。Minor collection 的过程就是将eden和在survivor space 中的活对象复制到空闲的 survivor space中。对象在 young generation里立即鞥了一定次数的minor collection后就会被移到 old generation中 称为tenuring

4、GC触发条件

YGC

触发条件:eden区空间不足

触发过程:清空年轻代中所有不被引用的对象,将enden和s1中的所有活对象复制到s2中。一些对象将复制到old区(s2中放不下的;存活次数超过turning threshold中的;重新计算tenuring threshold(serial parallel GC会触发此项);重新调整Eden 和from的大小(parallel GC会触发此项);)

注意:全过程暂停应用是否为多线程处理有具体的GC决定

查看方式:jstat –gcutil gc log

Full GC

触发条件:old区空间不足 perm空间不足 显示调用System.GC、RMI等待定时触发YGC时的悲观策略dump live 的内存信息(map -dump:live)时

触发过程:清空heap中不引用的对像permgen区中已经被卸载的class loader中加载的class信息。 如配置了 collectGenORirst则先触发YGC(针对serial GC)

注意:全过程暂停应用 是否为多线程处理取决于具体的GC决定

查看方式:jstat -gcutil gc log

非堆内存默认不GC 可以设置GC这个要看使用的垃圾收集器 CMS策略可以对PermGen进行GC 设置参数是 -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled 1.6之前还要加入-XX:+CMSPermGenSweepingEnabled

堆内存GC

JVM(采用分代算法),用较高的频率对年轻的对象(young generation)采用复制算法进行YGC,而对老对象(tenured generation)较少(tenured generation 满了后才进行)回收,采用标记整理算法进行Full GC。这样就不需要每次GC都将内存中所有对象都检查一遍。

非堆内存不GC

GC不会在主程序运行期对PermGen Space进行清理,所以如果你的应用中有很多CLASS(特别是动态生成类,当然permgen space存放的内容不仅限于类)的话,就很可能出现PermGen Space错误。

总结:

New 对象优先在Eden区

大对象直接进入老年代 有参数设置,超出这个大小进入老年区

长期存活的对象直接进入老年代 默认设置: age=15

class,变量等信息JVM直接加载进入持久代(1.8及以后没有永久代用元空间替代)

老年代和持久代(1.8及以后没有永久代用元空间替代)都会触发full GC

Young GC 只会发生在Eden区

Full gc 时占用时间较长,而在触发GC的时候,会暂停所有线程而full gc的时间较长,所以full gc 的核心思想:

1) 尽可能减少full gc 的次数

2) 尽可能的延长 full gc 的间隔时间

堆内存分布:3/8 堆内存=young

5/8 堆内存=old

young=1:1:8(S1:S2:eden)

GC 作用:1.分配内存 2.确保被引用的对象不被回收 3.回收不可达对像

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值