首先说对象的内存分配,就是在堆上分配,再细致下来就是分配在Eden去上,也有其他的情况的实现,但是具体的细节,取决于使用了什么样的垃圾收集器组合,以及相关的虚拟机配置
1.对象优先在Eden区进行分配
大多数时间,新生的对象会在Eden区内创建好,但Eden区可能出现空间不够分配的时候,虚拟机先进行一次MinorGC
然后虚拟机提供了-XX +PrintGCDetails这个收集器日志参数
进行垃圾回收的时候打印日志出来
我们通过-Xmn来设置新生代大小
然后通过SurvivorRatio=8来指定Eden和Survivor去的比例
2.大对象直接进入老年代
所谓大对象,就是指大量需要连续内存看空间的对象,常见的就大的数组,大对象对于Java的来说,不是个好消息
因为新生代本来所拥有的的空间那就不多,在遇到大对象的时候不得都不提前垃圾收集
虚拟机为了避免这个问题,提供了一个XX PretenureSizeThreshold参数,大于这个设定值的对象直接在老年代分配
避免进行大量的内存复制
3.长期存活的对象直接进入老年代
虚拟机采用了分代管理,那么如何做到让对象从新生代到老年代这样一个过渡
这是利用了年龄计数器,将一个对象在创建之初就将其的年龄设置为1,对象在Survivor区熬过一次MinorGC,年龄就增大1岁,然后增到一定程度就会升为老年代,然后一般默认是15岁
这个晋升阀值,默认是15,可以ton过-XX:MaxTenuringThreshold设置
4.动态对象年龄判断
为了更方便的晋升,虚拟机并没有死要求对象年龄一定到达晋升条件才能晋升,
譬如,在Survivor中相同年龄的对象大小占用在Survivor空间的一般,就能直接将大于等于这个年龄的对象进行晋升
5.内存分配担保
在发生Minor GC之前,虚拟机会先检查老年代最大可用连续空间是否大于了新生代所有空间,不成立则查看是否可以进行冒险的MinorGC,如果不允许MinorGC,则进行Full GC