Java 中把声明变量的语句如果写在循环体内,每次执行时栈内存中的变量和数据是如何变化的?

问题一:如下面的代码示例 1,JVM 是不是会反复回收旧的变量 a 再重新创建新的变量 a 呢?还是旧的变量 a 一直保留在栈内,只是反复赋值 0 而已呢?

代码示例 1:

while (true) {
int a = 0;
a = 5;
}

问题二:如下面的代码示例 2,循环体内的引用数据类型变量 p3 是否会先回收再新建,还是保留旧的变量 p3,只是反复对其赋值而已呢?

代码示例 2:

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

正确答案:旧变量依旧保留在栈内,只是反复赋值。

基本类型变量 a 和引用类型变量 p3 都不会因为声明变量的语句在循环体内而不断地重新创建,变量一直存在栈内存中,只是循环的赋值而已,只是循环地对变量 a 和变量 p3 读写数据而已。

参考答案:

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

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

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

  • 在堆内存里面发生的回收:由垃圾回收器进行回收,会把不再可用的对象进行回收。
  • 在栈内存里面发生的回收:栈内存是由栈帧组成的,局部变量都是在栈帧里面定义的,所以局部变量的回收,是随着栈帧的销毁而被回收的。而栈帧的销毁,是在方法调用完成之后。

在弄清楚“回收”的概念之后,再回到问题。

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

再看问题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语句中的变量都是在局部变量表中占用了一个槽位,并且对这个槽位反复读写,所以称不上是“回收”。

参考地址:https://www.zhihu.com/question/439157488

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Speedment 3.0.17及更高版本简化了事务

交易次数 有时我们想确保我们的数据库操作是原子执行的,并且与其他操作分开。 这是交易起作用的地方。 交易是一组操作 数据库可能接受或不接受作为原子操作的建议。 因此,要么接受交易中的所有操作,要么不接受交易中的所有操作。 事务的另一…

python中常用的方法

python常用方法 字符串: name.title() #字符串的每个单词首字母大写 name.upper() #字符串的字母全部大写 name.lower() #字符串的字母全部小写 name.rstrip() #删除字符串结尾的空白 name.lstrip() #删除字符串开头的空白 name.strip() #删除…

sql server 2008 年累计数_Windows Server 2008 和 SQL Server 2008将终止支持 迁移至Azure 微软提供3年免费技术支持...

点击上方蓝色字关注我们~迁移至 Azure 并利用免费扩展安全更新。了解有关支持终止建议的更多信息,请使用浏览器访问:https://www.microsoft.com/zh-cn/sql-server/sql-server-2008.对您意味着什么1 2017年基于风险的安全报告; 思科 2017 年度网络安全报告…

递归调用方法时栈内存是如何变化的?(使用内存图演示递归调用过程)

文章目录 什么是栈内存演示方法递归调用过程什么是栈内存 在学习递归实现原理之前,我们先了解一下栈内存。 栈内存是计算机中的一种数据存储方式,是 Java 进程启动时候在内存中开辟的存储空间。 栈内存的利用方式遵循 LIFO(后迚先出)原则Java 所有局部变量都在栈中分配(压入…

旧版Requests库

requests库基本使用Requests解析库方法response对象response对象的属性**r.encoding**属性与**r.apparent_encoding**属性的区别requests库的异常举例Requests解析库 方法 最常用的两个方法: request.get() request.post() 作用:都是从服务器获取网页信息 区别&…

运行单个源文件_使用一个命令执行单个Java源文件

运行单个源文件JDK增强提案 ( JEP ) 草案于2017年末创建,名为“ 启动单文件源代码程序 ”(其相关的JDK问题为JDK-8192920 )。 顾名思义,该JEP草案旨在“增强Java启动器以支持运行作为Java源代码的单个文件提…

夸克浏览器怎么安装脚本_iOS 第一浏览器发布安卓版,除了真香我还能说什么...

如果不算 Safari 的话,iOS 平台公认最好的浏览器是 Alook。无推送无新闻无广告、日常售价 12 元、工具类排行第三、7.8 万个评分足以证明其优秀。以至于很多双持或对 Alook 有所了解的用户都希望 Alook 能推出安卓端。现在安卓端真的来了。(安卓端免费)假如这个时候…

Windows 10 笔记本如何使用外接显示器

文章目录如何连接外接显示屏如何设置显示模式如何设置不同显示屏各自的分辨率如何设置主显示器通过显卡来设置显示器如何连接外接显示屏 VGA 线或者 HDMI 线连接好电脑和显示器,以 HDMI 线为例简单讲下吧。 显示器可能会有多个 HDMI 接口,假设你插入 H…

蓝牙信号强度检测app_基于蓝牙技术的智能插座方案

有这样一句话“科技时代,生活轻快”。随着社会现代化程度越来越高,科技的应用为人们的生活带来便捷,大大提高了工作效率。纵观市场上“智能家居”产品很多,功能各异,各有千秋,但是针对家电控制的智能插座还…

图片清晰度,分辨率,像素总结

像素 像素是一个个小方块,是构成位图的基本单位。将图片放大即可看出来,如图: 分辨率 显示分辨率是指像素的总数量,如上图的22001400,也就是宽有2200个像素,高有1400个像素。 图像分辨率是指每英寸所包含…

apache isis_使用Apache Isis快速进行SEMAT应用程序开发

apache isisTL; DR这是关于一个帖子会谈SEMAT宠物项目我创建使用Apache伊希斯和部署到OpenShift在线这里http://semat.ofbizian.com Apache Isis 作为主要在后端系统上工作的Java开发人员,我讨厌创建用户界面和处理Java脚本。 幸运的是,有一些Java项目&…

MacBook外接显示器及相关设置详解(分屏/多屏)

文章目录一、连接显示器和电脑二、打开显示器设置界面三、调整显示器图标位置四、设置主显示器五、移动 Dock六、镜像模式七、合盖模式八、扩展模式九、设置外接显示器竖屏显示十、外接显示器后,如何调出更多分辨率十一、关于程序坞显示的问题一、连接显示器和电脑 …

ibm liberty_使用Eclipse和Open Liberty的Java EE 8上的Java 9

ibm liberty几周前,我写了一篇文章,题目是哪个IDE和服务器支持Java EE 8和Java9 ,着眼于Java 9和Java EE 8之间的当前状态。您可以期望事情发展很快,现在我们有了一些alpha和支持Java 9和Java EE 8的开发版本。这些是– Payara 5…

inkscape生成g代码_三点二. 量子对抗生成网络 (Quantum GAN)

理论基础之前我们介绍了强化学习Leo:和Leo一起学量子计算:三点一. 微分线路和强化学习​zhuanlan.zhihu.com上面这篇博文告诉我们如何把量子线路类比为神经网络,并获取它的导数。在可微分线路的基础上,我们可以做一些更加酷的事情…

python用xpath爬取10页网站图片

#爬取网站图片 import requests from lxml import etree import osi0 #计数 #请求头 headers{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"} for x in range(…

MacBook外接显示器的显示模式介绍及设置说明(分屏/多屏)

文章目录一、显示模式的介绍(一)扩展模式(程序员开发模式)(二)合盖模式(三)镜像模式(四)混合模式二、显示模式的设置(一)扩展模式设置…

aws fargate_借助Fargate和EKS,AWS甚至可以实现Cloud-ier和Kuberneties-ier

aws fargate在本周的re:Invent大会上,AWS宣布了很多很棒的事情。 您应该检查一下他们的页面 ,以了解他们正在做的所有新工作的概况–内容很多,而且很多看起来立即有用。 如果您想了解更多信息,我的同事凯利安德鲁斯&am…

关键词分词工具_快图制作工具 | 如何制作词云图?

点击蓝字关注我们如何制作词云图?首先,我们需要对“词云”有个简单的概念。“词云”这个概念最先由美国西北大学新闻学副教授、新媒体专业主任里奇戈登(Rich Gordon)提出。“词云”(别名:文字云,外文名:wordle)即由词汇…

机器学习西瓜书各章详细目录定位

第一章 绪论 1.1 引言(P1) 1.2 基本术语(P2) 1.3 假设空间(P4) 1.4 归纳偏好(P6) 1.5 发展历程(P10) 1.6 应用现状(P13) 1.7 阅读材料(P16) 第二章 模型评估与选择 2.1 经验误差与过拟合(P23) 2.2 评估方法(P24) 2.2.1 留出法 2.2.2 交叉验证法 2.2.3 自助法 2.3 性能…

表达式中常用到的运算符

文章目录分组一元运算符算数运算符逻辑移位按位“与”按位“或”按位“异”赋值表达式分隔符分组 () 一元运算符 ! ~ - 算数运算符 * / % - 逻辑移位 << >> 按位“与” & 按位“或” | 按位“异” ^ 赋值 * / % - & ^ | << >>…