java jvm内存地址_面试系列之Java对象在JVM内存中如何分配与流转的?

其实,JVM的垃圾回收还是有挺多可以去深入理解的,就比如经常遇到的一个面试题:Java对象在JVM内存中如何分配与流转的?

在浅谈垃圾回收的上篇中,我简单的说到,但是仅仅是这样,还不够深入的理解到对象内存的分配,因此,今天我们就来深入理解Java对象在JVM内存的过程。

在前面我也讲了,平时我们创建出来的对象,一般都分为两种:

一种是短期存活的,主要分配在Java堆内存之后,用完后很快会被垃圾回收,因此该对象在Java对内存的年轻代中。

另一种是长期存活的,这种事不断被引用的,所以会一直在Java堆内存中,因此该对象在Java堆内存的老年代中。

因此,我们先来思考两个问题,什么情况下会进入新生代?什么情况下会进入老年代?

大部分的正常对象都会优先在新生代分配内存

这里我们先来看一段代码:

// 静态变量staticVariable

private static StaticVariable staticVariable = new StaticVariable();

public static void main(String[] args) {

while (true){

staticVariable.fetch();

}

}

private static void loadReplicasFromDisk(){

// 局部变量加载

LocalVariable localVariable = new LocalVariable();

localVariable.load();

}

我们可以看到,类静态变量staticVariable引用的那个StaticVariable对象,是长期存活在内存的,但是哪怕是这样,我们一开始在new StaticVariable()的时候,也分配在年轻代中了,而loadReplicasFromDisk()方法创建的LocalVariable对象,也是一样被分配在年轻代中的。

下图我们可以看到对象的分配过程。

05f37cd50837a94e7124858b13b60661.png

而上面的代码,我们也可以看到,loadReplicasFromDisk()方法执行完毕后,这个方法就不会被引用了,因此这时候栈帧就会出栈,而该方法引用的LocalVariable对象也不会再使用了,因此这时候,会导致没有任何局部标量引用LocalVariable实例对象了。

如下图所示:

b1d61c93fd1506806e0c0d5e88d734c7.png

这时候,LocalVariable对象还不一定会被垃圾回收呢!因为我们代码中经常会创建很多对象,如果对象将预先分配的内存空间占满了,我们再去分配对象就会出现新生代内存空间不够了,这时候就会触发新生代内存空间的垃圾回收了,而新生代内存空间的垃圾回收也成为“Minor GC”,有时候我们也讲座“Young GC”,这个回收就会把刚刚所说的没人引用的对象(包括LocalVariable对象)进行回收了。

因此,在我们代码创建大部分对象时,很多都是这种使用之后立马就可以回收掉的生存周期极短的对象。发现新生代内存空间不足后,就会触发一次“Young GC”,把所有垃圾对象都回收掉。

9f5b39f1d9529d8b7b33321d9a454b81.png

那如果是长期存活的对象会一直在新生代中?

在上面的代码中,我们看到了StaticVariable对象是一直被静态变量所引用的长期存活对象,尽管新生代满了会进行一次“Minor GC”,但是这个StaticVariable对象是一直会存活在新生代中的。

因此在JVM中,有一个规定,如果一个实例对象在新生代中成功躲过十五次垃圾回收,就可以被认为是老年代的对象了,也会被认为是会长期存活的对象。

这时候可能会想,进入老年代,难道就可以一直存活下去了吗?当然不是,当年老代快满的时候,那些不在被任何人引用的对象,也需要被垃圾回收的,而老年代的回收机制则成为“Full GC”,这种回收的时间成本就比较高了,因此如果频繁的经历“Full GC”,系统也会变得十分卡顿,这时候我们就需要查看是那些对象占用的内存较多了。

8d59748511c6d8cb5c341bdd3a35847e.png

这里我们总结一下就是,我们的对象都是有限分配到新生代的,而年轻代如果对象满了,就会触发“Minor GC”来回收掉没人引用的垃圾对象,如果躲掉了十多次的垃圾回收,就会进入老年代,如果老年代也满了,就会触发“Full GC”,把老年代引用的垃圾对象清理掉。

本篇也只是针对面试题进行理解和思考,当然,主要是理论为主,没有过多的深入底层,以后也会发一些面试题总结和理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值