JAVA中的栈和堆
JAVA在程序运行时,在内存中划分5片空间进行数据的存储。分别是:1:寄存器。2:本地方法区。3:方法区。4:栈。5:堆。
基本,栈stack和堆heap这两个概念很重要,不了解清楚,后面就不用学了。
以下是这几天栈和堆的学习记录和心得。得些记录下来。以后有学到新的,会慢慢补充。
一、先说一下最基本的要点
基本数据类型、局部变量都是存放在栈内存中的,用完就消失。
new创建的实例化对象及数组,是存放在堆内存中的,用完之后不定期自动消除。
二、先明确以上两点,以下示例就比较好理解了
示例1
main()
int x=1;
show ()
int x=2
主函数main()中定义变量int x=1,show()函数中定义变量int x=1。最后show()函数执行完毕。
以上程序执行步骤:
第1步——main()函数是程序入口,JVM先执行,在栈内存中开辟一个空间,存放int类型变量x,同时附值1。
第2步——JVM执行show()函数,在栈内存中又开辟一个新的空间,存放int类型变量x,同时附值2。
此时main空间与show空间并存,同时运行,互不影响。
第3步——show()执行完毕,变量x立即释放,空间消失。但是main()函数空间仍存在,main中的变量x仍然存在,不受影响。
示意图如下:

——————————————————————————————————————————————————————————————————————
示例2
main()
int[] x=new int[3];
x[0]=20
主函数main()中定义数组x,元素类型int,元素个数3。
以上程序执行步骤
第1步——执行int[] x=new int[3];
隐藏以下几分支
JVM执行main()函数,在栈内存中开辟一个空间,存放x变量(x变量是局部变量)。
同时,在堆内存中也开辟一个空间,存放new int[3]数组,堆内存会自动内存首地址值,如0x0045。
数组在栈内存中的地址值,会附给x,这样x也有地址值。所以,x就指向(引用)了这个数组。此时,所有元素均未附值,但都有默认初始化值0。
第2步——执行x[0]=20
即在堆内存中将20附给[0]这个数组元素。这样,数组的三个元素值分别为20,0,0
示图如下:

——————————————————————————————————————————————————————————————————————
示例3
main()
int[] x=new int[3];
x[0]=20
x=null;
以上步骤执行步骤
第1、2步——与示例2完全一样,略。
第3步——执行x=null;
null表示空值,即x的引用数组内存地址0x0045被删除了,则不再指向栈内存中的数组。此时,堆中的数组不再被x使用了,即被视为垃圾,JVM会启动垃圾回收机制,不定时自动删除。
示图如下

——————————————————————————————————————————————————————————————————
示例4
main()
int[] x=new int[3];
int[] y=x;
y[1]=100
x=null;
以上步骤执行步骤
第1步——与示例2第1步一致,略。
第2步——执行int[] y=x,
在栈内存定义了新的数组变量内存y,同时将x的值0x0045附给了y。所以,y也指向了堆内存中的同一个数组。
第3步——执行y[1]=100
即在堆内存中将20附给[0]这个数组元素。这样,数组的三个元素值分别为0,100,0
第4步——执行x=null
则变量x不再指向栈内存中的数组了。但是,变量y仍然指向,所以数组不消失。
示图如下

三、栈和堆的特点
栈:
函数中定义的基本类型变量,对象的引用变量都在函数的栈内存中分配。
栈内存特点,数数据一执行完毕,变量会立即释放,节约内存空间。
栈内存中的数据,没有默认初始化值,需要手动设置。
堆:
堆内存用来存放new创建的对象和数组。
堆内存中所有的实体都有内存地址值。
堆内存中的实体是用来封装数据的,这些数据都有默认初始化值。
堆内存中的实体不再被指向时,JVM启动垃圾回收机制,自动清除,这也是JAVA优于C++的表现之一(C++中需要程序员手动清除)。
注:
什么是局部变量:定义在函数中的变量、定义在函数中的参数上的变量、定义在for循环内部的变量
JAVA中的栈和堆的更多相关文章
- 浅谈Java中的栈和堆
人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中? 这里浅谈Java中的栈和堆 首先,将结论写在前面,后面再用例子加以验证. Java的栈中存储以下类型数 ...
- Java中的栈,堆,方法区和常量池
要说Java中的栈,堆,方法区和常量池就要提到HotSpot,HotSpot是Sun JDK 和 Open JDK中所带的虚拟机. (Sun JDK 和 Open JDK除了注释不同,代码实现基本上是 ...
- JAVA中的栈和堆【转】
原文链接 https://www.cnblogs.com/ibelieve618/p/6380328.html JAVA在程序运行时,在内存中划分5片空间进行数据的存储.分别是:1:寄存器.2:本地方 ...
- java中的内存空间 堆和栈
认识堆与栈 栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆.Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过 ...
- Java 中的 JVM、堆和栈 -- 初步了解
JVM -- Java Virtual Machine(Java虚拟机) —— 因为要说堆和栈,所以我们必须要先简单的说一下JVM.(JVM详细请找度娘啦~) 首先,我们都知道 java 一直宣传的口 ...
- 如何给女朋友讲明白:Java 中 Stack(栈) 与 Heap(堆)
背景 Java 中 Stack(栈) 与 Heap(堆) 是面试中被经常问到的一个话题. 有没有对 Java 中 Stack(栈) 与 Heap(堆) 烂熟于心的童鞋,请举手!!!(怎么没人举手-) ...
- 关于VS中更改栈和堆空间的大小
编号:1008时间:2016年4月12日17:01:38功能:关于VS中更改栈和堆空间的大小 URL:http://blog.csdn.net/icerock2000/article/details/ ...
- js 中的栈和堆
js中的栈与堆的讲解/基本数据类型与引用类型的讲解 前言:1. 学习前端,入门简单,想学好确实是一件很困难的事情,东西多而且杂,版本快速迭代,产品框架层出不穷. 2. 前端学习成本确实很高,需要不断的 ...
- java中的栈(利用数组实现栈)
java中的栈(利用数组实现栈) 常见的数据结构:https://blog.csdn.net/weixin_43304253/article/details/119764275 栈的介绍 1.栈的英文 ...
随机推荐
- PHP和MySQL Web开发(原书第4版) 高清PDF+源代码
PHP和MySQL Web开发(原书第4版) 高清PDF+源代码 [日期:2014-08-06] 来源:Linux社区 作者:Linux [字体:大 中 小] 内容简介 <PHP和My ...
- SecureCRT上传bash: rz: command not found
SecureCRT上传bash: rz: command not found -bash: rz: command not found rz命令没找到? 执行sz,同样也没找到. 安装lrzs ...
- (中等) POJ 1054 The Troublesome Frog,记忆化搜索。
Description In Korea, the naughtiness of the cheonggaeguri, a small frog, is legendary. This is a we ...
- OPENCV图像变换-2
一.经典霍夫变换 霍夫变换是图像处理中的一种特征提取技术,该方法通过在一个参数空间中通过计算累计结果的局部最大值来得到一个符合该特定形状的集合,作为结果. 运用两个坐标空间之间的变换,将一个空间中具有 ...
- kvm下Windows激活方式小计
使用kvm创建widnwos镜像模板,镜像模板默认是已经激活的正版系统,但是使用程序拷贝部署到不同的机器后发现已经激活的系统变成未激活状态,我们需求就是需要拷贝到不同的机器也能显示是正版系统 网上找了 ...
- 如何在我自己的web 项目的jsp页面中添加链接,直接让别人通过内网在我的电脑上下载文件
今天接到一个任务,将昨天年会的视频,音频,图片等放在公司自己的服务器上,使连接同一个路由器的(即同一个内网)的同事可以通过内网下载视频(通过内网下载,可以提高下载速度). 备注:本次用的是tomcat ...
- 7 -- Spring的基本用法 -- 12...
7.12 Spring 3.0 提供的表达式语言(SpEL) Spring表达式语言(简称SpEL)是一种与JSP 2 的EL功能类似的表达式语言,它可以在运行时查询和操作对象图.支持方法调用和基本字 ...
- Freemarker入门案例
Freemarker入门案例 首先需要到freemarker官方下载freemarker的jar包,导入到项目中,如:freemarker-2.3.19.jar 1.先建个freemarker的工具类 ...
- C#中的逆变和协变
msdn 解释如下: “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型. “逆变”则是指能够使用派生程度更小的类型. 解释的很正确,大致就是这样,不过不够直白. 直白的理解: “协变” ...
- 企业建站http://www.douco.com/
http://www.douco.com/ 非常方便的,搭建简单的企业网站