面试的时候常问到垃圾回收这一块,然后面试者经常会回答到当分配的对象达到一定阈值的情况下会直接到老年代。但是查了下,这个好像并没有哪里有个明确的说明。然后用deepseek也搜索了下,回答还不一样,有的回答是并没有这个阈值(意思是只要eden区能装下,就放入到eden区),有的回答是“JVM 会根据 Eden 区的剩余空间和对象大小决定是否直接将大对象分配到 Old 区”。让人有点懵,今天做个实验:
新建个测试用例(使用的是jdk8):
先试用默认的垃圾收集器:Parallel Scavenge(新生代) + Parallel Old(老年代)
启动应用,打开jvisualVM.
执行一个分配200M内存的方法:
内存也还是在eden区:
连续执行2次方法,发现eden区分配了200M,还有200M是直接到了老年代(此时eden区还有几十兆的空间):
执行一次生成300M对象的方法(直接到了old区):
使用CMS垃圾收集器验证:
重启应用,调用一次方法,生成250M对象,发现还是eden区:
多次调用方法(生成260M对象),发现一直是在eden区,只是每调从第二次开始每调一次的时,垃圾收集次数就增1:
从上面的验证来看,在默认情况下,面试中常说的达到一定阈值后会直接分配到老年代是有一定道理的。但是从cms收集器的测试来看,又感觉是没有这个阈值,只要eden区不够,就进行垃圾回收。所以感觉上面deepseek说的情况可能就是分别对应了jdk8默认的垃圾收集器和cms收集器了。