JVM垃圾回收这就是你心心念念的内存分配和回收策略
文章目录
- JVM垃圾回收这就是你心心念念的内存分配和回收策略
- 1、对象分配内存
- 1、概念上:在堆上分配
- 2、经典分代上:新生对象会分配在新生代中,少数情况下因为对象体积过大超过一定阀值也可能会直接分配在老年
- 2、对象优先在Eden(伊甸园)分配
- 新生代中的
- 3、大对象直接进入老年代
- 为什么要进入老年代
- 4、长期存活的对象将进入老年代
- 怎么将对象放在老年代中
- 5、动态对象年龄判定
- 为什么要对年龄进行判定 :
- 6、空间分配担保
英文单词心心念:
concurrent :同步的
java 技术体系的自动内存管理 ,最根本的目标是自动化的解决两个问题:
自动给对象分配内存以及自动回收分配给对象内存
1、对象分配内存
1、概念上:在堆上分配
2、经典分代上:新生对象会分配在新生代中,少数情况下因为对象体积过大超过一定阀值也可能会直接分配在老年
对象分配是不固定的,具体分配在哪一个块 取决于垃圾收集器 以及虚拟机中内存相关的参数
2、对象优先在Eden(伊甸园)分配
大多数情况下 对象在新生代eden区中 分配,当eden没有足够空间进行分配 虚拟机进行minor GC
HotSpot虚拟机提供了-xx +PrintGCDetails 收集器参数
虚拟机在发生垃圾收集行为时打印内存回收日志,并且在进程退出的时候输出当前的内存各区域的分配情况
新生代中的
Eden区与一个Suivivor区的空间分配空间的比例时8:1 toSurvivor 1 fromSurvivor 1 新生代的课用空间就是 9
当新生代的大小不足以放在新对象的大小就将该对象放入老年代中进行保存
3、大对象直接进入老年代
为什么要进入老年代
大对象是指需要大量连续内存空间的Java对象,最典型的大对象就是内存很大的字符串
大对象对虚拟机内存来说就是一个不折不扣的坏消息 这还是不是 最让人崩溃的 尤其遇见一群 存活时间短的大对象
在分配空间时,明明还有不少空间就提前触发垃圾收集收集 当复制算法就意味着高额的内存复制开销
-XXPreTenureSizeThreshold参数 指定大于设置的阀值直接在老年代分配
这种做就是目的就是避免时eden区以及连个suivivor区之间来回复制 产生大声的内存复制
4、长期存活的对象将进入老年代
HotSpot 虚拟机中多数收集器都采用了分代收集来管理堆内存,内存回收必须能决策 哪些防新生代 放老年代
怎么将对象放在老年代中
为了做到 虚拟机给每一个对象定义了一个对象年龄计数器
存储在对象头中
对象通常在Eden区里诞生 如果经过Minor GC 后仍然存活 并且被Surivor容纳的话
该对象就会被移动到Survivor空间中
该对象设为1岁,对象在Surviuvor区没熬过一次Minor GC 当他年龄增加 到默认到15 就会晋升老年代中 对象晋升老年代的年龄阀值
5、动态对象年龄判定
为什么要对年龄进行判定 :
为了更好的适应不同程度的内存状况 HotSpot 虚拟机并不是永远要求对象的年龄必须
达到–XX :MaxTenuringThreshold才能晋升到老年代
如果所有的对象大小的总和大于Survivor空间的一半 年龄大于或等于该年龄对象的可以直接进入到老年代
6、空间分配担保
在发生Minor GC 之前 虚拟机必须先检查老年代最大可用的连续空间是否大于新生代所有对象的总空间 如果条件成立 这一次MinorGC可以确保是安全的
如果不成立 则虚拟机会先查看-XX HandlePromitionFailure 参数是否允许担保失败
如果允许 就会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平军大小
如果大于 就是尝试一次MInorGC 有风险
如果小于就不允许有风险 就要改为进行一次full GC、
大可用的连续空间是否大于历次晋升到老年代对象的平军大小
如果大于 就是尝试一次MInorGC 有风险
如果小于就不允许有风险 就要改为进行一次full GC、