内存分配与回收策略
Java的相较于C++的方便之处在于,可以自动化地解决两个问题:给对象分配内存以及回收分配给对象的内存。前面花了大量的篇幅介绍回收,现在来总结以下内存分配的一些策略。
1. 对象优先在Eden分配
多数情况下,对象在新生代Eden中分配,如果没有足够的空间,则会进行一次MinorGC。
-XX:+PrintGCDetails可以在发生垃圾收集时打印内存回收日志
2. 大对象直接进入老年代
所谓大对象是指,需要大量连续内存空间的JAVA对象,最典型的就是很长的字符串以及数组。经常出现大对象容易导致内存还有不少空间的时候就提前触发垃圾收集以获取足够的连续空间。
-XX:PretenureSizeThreshold用来设置大对象的阈值,即超过这个值的对象会直接被分配到老年代,这样做的好处是能避免在Eden区及两个Survivor之间发生大量的内存复制。另外这个参数只能写具体数字,不能加单位,比如3MB得写出3145728
3.长期存活的对象将进入老年代
为了识别哪些对象应该放在新生代,哪些对象应该放在老年代,虚拟机给每个对象定义了一个对象年龄计数器。如果对象出生在eden并且多次minorGC后都仍然存活,那么每次GC,年龄就增加1岁,默认15岁以后,就会晋升到老年代。可以通过-XX:MaxTenuringThreshold进行设置。
4.动态对象年龄判定
为了更好地适应不同程序的内存状况,虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋升老年代,如果在Survivor中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代。
网友评论