JVM知识总结--内存分配策略

对象的内存分配主要是在堆上进行的,也有可能在JIT编译后被拆散为标量类型并间接的在栈上分配,对象主要分配在Eden区,若是启动了TLAB,则优先分配到TLAB上,少数状况下可能直接分配到老年代中;总的来讲对象的分配有大体的规则和模式,但无必定之规,具体的分配逻辑与使用的GC收集器类型和配置的JVM参数都会有关系。数组

Minor GC 和 Full GC

  1. Minor GC:发生在新生代的垃圾收集动做,频率高、速度快;
  2. Full GC/Major GC:发生在老年代的GC,一般会伴随至少一次的Minor GC,通常会比Minor GC慢10倍以上;

最广泛的几条内存分配原则以下:

  1. 对象优先在Eden区分配:当Eden区没有足够的空间时,虚拟机会发起一次Minor GC;
  2. 大对象直接进入老年代:大对象是指须要大量连续内存空间的对象,典型的大对象就是很长的字符串或数组,虚拟机提供了-XX:PretenureSizeThreshold参数(仅针对Serial和Par New收集器有效),大于此设置值的对象会直接放入老年代;
  3. 长期存活的对象将进入老年代:为了在内存回收时识别哪些对象放在年轻代,哪些放在老年代,VM给每一个对象定义了一个对象年龄计数器(Age),对象在第一次Minor GC后仍存活并被移动到Survivor中后Age会被设为1,之后每通过一次Minor GC age都会加1,age增长到15(默认值)后,对象会被移动到老年代中,对象晋升到老年代的age阈值能够经过-XX:MaxTenuringThreshold来设置;
  4. 动态对象年龄断定:为了更好的适应不一样程序的内存状况,若是在Survivor空间中相同年龄的全部对象大小总和大于Survivor空间的一半,则年龄大于等于此年龄的对象能够忽略3中的配置直接进入老年代;
  5. 空间分配担保:在发生Minor GC前,vm会先检查老年代的最大可用连续空间是否大于新生代对象的总空间,若是小于,虚拟机会查看HandlePromotionFailure是否容许担保失败,若是容许,vm会继续检查老年代的最大可用连续空间是否大于历次晋升到老年代的对象的平均大小,若是大于,将会尝试进行一次Minor GC,若是小于或HandlePromotionFailure设置为不容许失败,会先进行一次Full GC,总的来讲,这是为了保证在Minor GC发生时老年代有足够的连续空间存放可能会重新生代晋升来的对象而采起的一项措施,为了不频繁的Full GC,HandlePromotionFailure一般会被设置为True;另外,在JDK 6 Update 24以后,HandlePromotionFailure参数再也不生效,只要老年代的可用连续空间大于新生代对象总和或历次晋升的平均大小,就会进行Minor GC,不然进行Full GC
相关文章
相关标签/搜索