java中声明变量的语句如果写在循环体内

首先,先明白一个概念,什么是“回收”?

大家都知道,JVM的内存结构有两个主要的区域:堆内存和栈内存

那么回收也是有相应的两个层面的:

  • 在堆内存里面发生的回收:由垃圾回收器进行回收,会把不再可用的对象进行回收。
  • 在栈内存里面发生的回收:栈内存是由栈帧组成的,局部变量都是在栈帧里面定义的,所以局部变量的回收,是随着栈帧的销毁而被回收的。而栈帧的销毁,是在方法调用完成之后。
  1. 在弄清楚“回收”的概念之后,再回到问题。先看问题1:
while (true) {
  int a = 0;
  a = 5;
}

这段代码里面,很明显,变量a是一个局部变量,而且是原始类型的局部变量,所以它的内存分配是在栈上,确切地说是在栈帧里面的局部变量表里面。而局部变量表这个东西,是在编译期间就确定的,它类似一个数组,里面包含了一些“槽位”来存放局部变量。那么,a这个变量,就是在局部变量表中的某一个槽位里面。并且a只会占用一个槽位,while循环里面来来回回也是对这一个槽位的里面进行读写。这个严格来说,算不上是“回收”。

2. 再看问题2:

问题2和问题1基本上一样的,在while 循环体里面只是对局部变量表的一个槽位来进行读写。和问题1有点区别的地方只是,p1和p2两个对象都是引用类型的,他们分别指向了堆内存的两个对象,并且这两个位于堆内存中的对象是没有变化的。

3. 顺着题主的思路,我猜测应该还有一种情况也是题主关心的,就是下面这种情况:

while (true) {
  Person p1 = new Person();
  Person p2 = p1;
}

在这种情况里面,while 循环体里面会有两个局部变量p1和p2,他们也会在局部变量表中占用两个槽位。在每一次循环中,new Person() 这个语句都会在堆内存创建一个新的对象,并且把p1变量指向这个新建的对象,随后p2 也会指向相同的对象。所以这个例子里面,堆内存中会在不停地创建对象,而这个大量对象的创建,会触发到堆内存里面的垃圾回收,垃圾回收器会把这些创建后又没使用的一大堆Person对象给回收掉。所以这个过程就是在 “不停创建” -- “垃圾回收”之间来回切换,进而导致内存的占用会忽上忽下,这种现象也被称为“内存抖动”。“内存抖动”是比较耗性能的,应该在实际应用中尽量避免。

综上,题目中的两个问题,简单来说就是:while语句中的变量都是在局部变量表中占用了一个槽位,并且对这个槽位反复读写,所以称不上是“回收”。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值