深刻理解Java虚拟机:JVM高级特性与最佳实践(三):内存分配与回收策略

java技术体系中所提倡的内存管理最终能够归为自动化的解决了两个问题:给对象分配内存已经回收分配给对象的内存。java

对象优先在Eden分配算法

 大多数状况下,对象在新生代Eden区中分配,当eden 区没有足够的空间进行分配时,虚拟机将发起一次Minor GC。 虚拟机提供了-XX:+PrintGCDetails 这个收集器日志参数,告诉虚拟机在发生垃圾收集行为时打印内存回收日志,而且在进程退出的时候输出当前内存各区域的分配状况。数组

大对象直接进入年老代spa

所谓大对象就是指,须要大量连续内存空间的java 对象。最典型的大对象就是那种很长的字符串极数组。虚拟机提供了一个-xx:pretenureSizeTreshold 参数,令大于这个设置值的对象直接在老年代中分配。这样作的目的是避免在Eden 区及两个Survivor区之间发生大量的内存拷贝。(复习一下新生代采用的是复制算法)日志

长期存活的对象将进入老年代
orm

虚拟机给每一个对象定义了一个对象年龄计数器,若是对象在Eden出生并通过第一次Minor GC 后仍然存活,而且能被Survivor 容纳的话,将被移动到Survivor 空间中,并将对象年龄设置为1.对象在在Survivor 中没熬过一次 Minor GC 。年龄就增长1岁,当它的年龄正经到必定程度(默认为15岁)时,就会被晋升到老年代中。
对象


总结进程

 年轻代(Young Generation):对象被建立时,内存的分配首先发生在年轻代(大对象能够直接被建立在年老代),大部分的对象在建立后很快就再也不使用,所以很快变得不可达,因而被年轻代的GC机制清理掉(IBM的研究代表,98%的对象都是很快消亡的),这个GC机制被称为Minor GC或叫Young GC。注意,Minor GC并不表明年轻代内存不足,它事实上只表示在Eden区上的GC。内存


 老年代:字符串

  老年代存储的对象比年轻代多得多,并且不乏大对象,对老年代进行内存清理时,若是使用中止-复制算法,则至关低效。通常,老年代用的算法是标记-整理算法,即:标记出仍然存活的对象(存在引用的),将全部存活的对象向一端移动,以保证内存的连续。

     在发生Minor GC时,虚拟机会检查每次晋升进入老年代的大小是否大于老年代的剩余空间大小,若是大于,则直接触发一次Full GC,不然,就查看是否设置了-XX:+HandlePromotionFailure(容许担保失败),若是容许,则只会进行MinorGC,此时能够容忍内存分配失败;若是不容许,则仍然进行Full GC(这表明着若是设置-XX:+Handle PromotionFailure,则触发MinorGC就会同时触发Full GC,哪怕老年代还有不少内存,因此,最好不要这样作)。

相关文章
相关标签/搜索