java 内存堆和栈_java堆内存和栈内存的处理

前段时间学习二叉树在处理删除操作的时候遇到一个头疼的问题:删除节点的时候明明已经置null了可树上该节点依旧存在,还必须执行node.father.left = null;才可以删除node节点,寻找了一下原因发现还是因为对java内存管理理解不够深入。

代码如下:

@Test

public void testNode() {

Node node1 = new Node("node1");

Node node2 = new Node("node2");

node2.father = node1;

node1.next = node2;

changeNode(node1.next);

System.out.println(node1.next.name);

}

private void changeNode(Node node3) {

node3 = null;

}

运行代码之后发现本来已经在changeNode()中已经设置node3 = null;可依旧能输出 node1.next.name。

要知为何?先理解几个概念:

1、栈内存存储基本类型的变量和对象的引用变量。

2、堆内存用于存放由new创建的对象和数组。每new一个对象就在堆内存中开辟一个新的存储空间存储此实例对象。

3、Person p = new Person();

执行new命令时程序执行两步:a:在堆内存中开辟一段空间,存储new出来的对象;b:在栈内存中添加一个变量p,p中存放的是该对象在堆内存中开始存放处的物理地址。

4、p = null;

执行此步骤的时候程序只是更改栈内存中的P变量所保存的地址,把地址指向null,而并没有操作堆内存(把p所指向的对象实例清空回收)。

5、无论是形参或者实参,执行 XXX = null;操作时都是把XXX变量栈中存储的地址改为指向null的地址。不操作堆中的数据。

下面就分析一下每步代码在堆内存和栈内存中的变化:

1、当new一个对象的时候,程序首先在堆内存中开辟一段空间实例化对象,同时在在栈内存中加入一个node1的变量,此变量中保存的是堆内存中物理地址的首地址。

bbd7356822345b0b201689aff5d78884.png

2、当调用方法传入参数的时候,在栈内存中添加一个局部变量node3,存储node2的物理首地址。也即是把node2的值0X00011拷贝进node3的栈内存中。

有网友说这是引用传递,其实传递的还是值,只不过node2的值本来就是物理地址,然后把这个物理地址值传给node3.

575bd47934b0fb02cd3d825e0016fb31.png

3、当执行node3 = null; 的时候,程序会把node3中的0X00011变为一个指向null的地址 0Xaaaaa.但是程序不对堆内存中数据进行管理(堆内存中没有引用指向的数据会在一定的时间通过GC进行处理)。

6bc2f25ee03aeaccb0eead8823ed68eb.png

可以看到执行到此步只是把变量中的物理地址置空,但并没有删除node2在堆内存中的数据,这正是为什么删除之后节点之后原数据依旧存在的原因。可以看到node1中的next依旧指向0X00011。

即使执行node2 = null,程序依旧不改变堆内存。

324c9fceb96ca85e40640fded8a58cd3.png

原数据依旧存在!

JVM内存处理实际情况要远远比这复杂得多,如果想深入了解可以找找 jvm内存处理机制相关资料,网上一搜一大堆,不再赘述。其实我也不知道。

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

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

相关文章

maven编译项目时提示:cached in the local repository

1.今天使用命令mvn compile编译maven项目时提示错误信息,部分错误信息如下: Failure to transfer wsdl4j:wsdl4j:jar:1.6.3 from http://xx.xx.xx.xx:8081/nexus/content/groups/public was cached in the local repository, resolution will not be re…

MS SQLSERVER中如何快速获取表的记录总数

(转自:http://www.cnblogs.com/pingkeke/archive/2006/05/29/411995.html)在数据库应用的设计中,我们往往会需要获取某些表的记录总数,用于判断表的记录总数是否过大,是否需要备份数据等。我们通常的做法是…

java 压缩指定文件_Java将指定文件/文件夹压缩成zip、rar压缩文件

import org.apache.tools.zip.ZipEntry;import org.apache.tools.zip.ZipOutputStream;import java.io.*;import java.util.zip.CheckedOutputStream;import java.util.zip.CRC32;/*** author chenssy** 将指定文件/文件夹压缩成zip、rar压缩文件*/public class ZipCompressor …

python基础(十三)

项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机的IT管理中的重要作用的,很多人觉得,堡垒机就是跳板机,其实这个认识是不全面的,跳板功…

使用 TABLESAMPLE 限制结果集

TABLESAMPLE 子句将从 FROM 子句中的表返回的行数限制到样本数或行数的某一百分比。例如: 复制代码 TABLESAMPLE (10 PERCENT) /*Return a sample 10 percent of the rows of the result set. */TABLESAMPLE (15 ROWS) /* Return a sample of 15 rows from the resu…

Catalan数(数论)

Catalan数 【参考网址】http://www.cnblogs.com/gongxijun/p/3232682.html 记得当时我们队写过一个,差点超时,现在找到了公式,感觉还是挺简单的。 还要注意,就算开long long 也只能表示到第33个,之后就会溢出。 &…

C#参考资料

C#参考资料 C# 读写XML文件 xmlDocumentC#时间函数c#读写XML文件在C#中使用异步Socket编程实现TCP网络服务的CS的通...C# socket传文件c#调用API要点

java面向_java是面向什么的语言?

Java是一门面向对象编程语言,不仅吸收了C语言的各种优点,还摒弃了C里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,…

RAISERROR (Transact-SQL)

来源: SQL Server 2005 联机丛书 生成错误消息并启动会话的错误处理。RAISERROR 可以引用 sys.messages 目录视图中存储的用户定义消息,也可以动态建立消息。该消息作为服务器错误消息返回到调用应用程序,或返回到 TRY…CATCH 构造的关联 CAT…

使用awk取passwd10-20行然后重定向

1、先找到要做实验的文件cp。 cp /etc/passwd /tmp/xusx 2、使用awk取passwd10-20的第三列从定向输出test.txt 第一步 awk NR>10 && NR<20 /tmp/xusx/passwd >>/tmp/xusx/test.txt 第二步 rootlocalhost xusx]# awk NR>10 && NR<20 /tmp/x…

jsp mysql做登入界面_用jsp实现网站登录界面的制作,并连接数据库

这里介绍一下怎样连接数据库&#xff0c;并用jsp制作一个简单的登录界面1.首先需要搭建好环境&#xff0c;有Tomcat&#xff0c;eslipse,jdk等&#xff0c;并配置好环境变量&#xff0c;并安装好数据库&#xff0c;这里我使用的数据库是mysql数据库&#xff0c;并下载了一个MyS…

decimal 和 numeric (Transact-SQL)

带固定精度和小数位数的数值数据类型。 decimal[ (p[ , s] )] 和 numeric[ (p[ , s] )] 固定精度和小数位数。使用最大精度时&#xff0c;有效值从 - 10^38 1 到 10^38 - 1。decimal 的 SQL-92 同义词为 dec 和 dec(p, s)。numeric 在功能上等价于 decimal。p&#xff08;精度…

java流的应用_Java中I/O流的应用

Java中I/O流的应用iLeGeNDpackagecom.hp.io;/** I/O流的应用 * 实现目标&#xff1a; * 首先创建一个文件 * 通过键盘向文件添加内容 * 然后把文件的内容打印到控制台 * */import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import ja…

PHP的反射类ReflectionClass、ReflectionMethod使用实例

PHP5 具有完整的反射API&#xff0c;添加对类、接口、函数、方法和扩展进行反向工程的能力。 反射是什么&#xff1f; 它是指在PHP运行状态中&#xff0c;扩展分析PHP程序&#xff0c;导出或提取出关于类、方法、属性、参数等的详细信息&#xff0c;包括注释。这种动态获取的信…

java 多线程跑数据_java——多线程的实现方式、三种办法解决线程赛跑、多线程数据同步(synchronized)、死锁...

多线程的实现方式&#xff1a;demo1、demo2demo1&#xff1a;继承Thread类&#xff0c;重写run()方法packagethread_test;public class ThreadDemo1 extendsThread {ThreadDemo1(){}ThreadDemo1(String szName){super(szName);}//重载run函数public voidrun() {for(int count …

word2007鼠标不好用

因为我装了 Powerdesigner 12.5&#xff0c;这个 COM 插件和 Word 2007 有冲突&#xff0c;所以导致了上面的问题&#xff0c;只要在 Word 移除这个 Addin 就可以了&#xff1a;左上角office图标——office选项——加载项——管理加载项——转到——去掉Powerdesigner Add-In前…

Axure5.1不能输入中文问题.

不能输入中文问题默认输入法改成“英语&#xff08;美国&#xff09;——美式键盘”。然后再进行切换就可以了。

java 静态线程_Java线程类静态本机void yield()方法(带示例)

线程类静态本机无效 yield()软件包java.lang.Thread.yield()中提供了此方法。yield()方法表示停止当前正在执行的线程&#xff0c;并为其他优先级相同的等待线程提供机会。如果没有等待线程&#xff0c;或者所有等待线程的优先级都较低&#xff0c;则同一线程将继续执行。这种方…

学习资料(不定更新)

w3cschool : http://www.w3school.com.cn/h.asp 菜鸟教程&#xff1a;http://www.runoob.com/ 51CTO: http://www.51cto.com/ angularjs: https://angularjs.org/ Python学习大本营: http://www.pythondoc.com/ http://webpy.org/ 比较好用的图表JS框架&#xff1a; http://www…