如何给女朋友讲明白:Java 中 Stack(栈) 与 Heap(堆)
背景
Java 中 Stack(栈) 与 Heap(堆) 是面试中被经常问到的一个话题。
有没有对 Java 中 Stack(栈) 与 Heap(堆) 烂熟于心的童鞋,请举手!!!(怎么没人举手…)
这个时候蜗牛哥的对象弱弱的举起了小手(这个对象不是 new 出来的哈)
女朋友:牛哥,谁要怼咱呀?我要不要先打个摇摇灵?
蜗牛哥:Heap(堆) 与 Stack(栈) 是两种内存区域,不是要干架(没文化真可怕…)
蜗牛哥:今天就来给你讲讲 Java 中 Stack(栈) 与 Heap(堆) 到底是什么?
女朋友:好呀,好呀,搞明白了堆与栈,我是不是就是 Java 高级工程师了?
蜗牛哥:有牛哥在,你还怕搞不明白???
女朋友:嘻嘻,我已经拿好我的小本本准备好记笔记了
蜗牛哥:好的,那咱们这就开讲
什么是 Stack(栈)内存?
Java 中的 Stack(栈)是内存的一部分,包含方法、局部变量和引用变量。Stack(栈)内存始终以 后进先出 顺序引用。在 Stack(栈)内存中创建局部变量。
什么是 Heap(堆)内存?
Heap(堆)是包含对象的内存部分,也可能包含引用变量。实例变量在 Heap(堆)内存中创建。
Java 中的内存分配
JVM 将内存划分为以下部分。
- Heap(堆)
- Stack(栈)
- Code(代码)
- Static(静态)
这种内存划分是有效管理内存所必需的。
- Code(代码) 内存包含所有您的字节码。
- Stack(栈) 内存包含所有方法、局部变量和引用变量。
- Heap(堆) 内存包含对象 (也可以含有引用变量)。
- Static(静态) 内存包含静态数据 / 方法。
本地和实例变量之间的区别
变量实例被声明在类中,但不包含方法内变量
class Student{
int num; // num为实例变量
public void showData{}
局部变量被定义在方法内部,包含方法参数。
public void sum(int a){
int x = int a + 3;
// a,x是局部变量;
}
栈和堆之间的区别
让我们举个例子来更好地理解这一点。
考虑一下你的 main 方法调用方法 m1
public void m1 {
int x = 20
}
在 java 栈中,将创建一个 frame(栈帧)在方法 m1 中。

m1 中的变量 X 也将在栈中为 m1 的 frame(栈帧)中创建(见下图)。

方法 m1 调用方法 m2。在 java 栈中,在 m1 的 frame(栈帧)顶部为 m2 创建一个新栈帧。


变量 b 和 c 也将在栈中的栈帧 m2 中创建。
public void m2(int b){
boolean c;
}

同样的方法 m2 是调用方法 m3。同样在栈顶部创建一个栈帧 m3(见下图)。


现在假设我们的方法 m3 正在为类 “Account” 创建一个对象,它有两个实例变量 int p 和 int q。
Account {
Int p;
Int q;
}
这是方法 m3 的代码
public void m3(){
Account ref = new Account();
// more code
}
语句 new Account() 将在堆中创建一个 Account 对象。

引用变量 “ref” 将在 java 堆中创建。

赋值 “=” 运算符将使引用变量指向堆中的对象。

一旦方法执行完,控制流程将返回调用方法。在里的情况,就是返回到方法 m2。

方法 m3 的栈将被刷新

由于引用变量 ref 将不再指向堆中的对象,因此它将符合垃圾回收的条件。

方法 m2 完成执行后。它将从堆栈弹出,其所有变量将被刷新,不再可用。
同样对于方法 m1。
最终,控制流程将返回程序的起始点。通常,就是 “main” 方法。
如果对象有一个引用作为其实例变量怎么办?
public static void main(String args[]) {
A parent = new A();
//more code
}
class A{
B child = new B();
int e;
//more code
}
class B{
int c;
int d;
//more code
}
在这种情况下,引用变量 “child” 将在堆中创建,而堆又将指向其对象,如下图所示。

总结一下:
- 调用方法时,会在栈顶部创建一个栈帧。
- 一旦方法完成执行,控制流将返回到调用方法,并刷新其相应的栈帧。
- 在栈中创建局部变量
- 实例变量在堆中创建并且是它们所属对象的一部分。
- 在栈中创建引用变量。
“不积跬步,无以至千里”,希望未来的你能:有梦为马 随处可栖!加油,少年!
关注公众号:「Java 知己」,每天更新 Java 知识哦,期待你的到来!
- 发送「1024」,免费领取 30 本经典编程书籍。
- 发送「Group」,与 10 万程序员一起进步。
- 发送「面试」,领取 BATJ 面试资料、面试视频攻略。
- 发送「JavaEE 实战」,领取《JavaEE 实战》系列视频教程。
- 发送「玩转算法」,领取《玩转算法》系列视频教程。

如何给女朋友讲明白:Java 中 Stack(栈) 与 Heap(堆)的更多相关文章
- JAVA Stack栈和Heap堆的区别(转)
首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆. 在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语: ...
- java - Stack栈和Heap堆的区别
首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆. 在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语: 堆存储 ...
- 逻辑运算符、三元运算符、for循环、stack(栈),heap(堆),方法区,静态域
Lesson One 2018-04-17 19:58:39 逻辑运算符(用于逻辑运算,左右两边都是 true 或 false) 逻辑与-& 和 短路与-&& 区别: & ...
- stack栈、heap堆的说明图
上面的两幅图是stm32系列的,但是基本原理可以通用的.
- 让你彻底明白JAVA中堆与栈的区别
原文地址:http://www.2cto.com/kf/201302/190704.html 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象 ...
- 浅谈Java中的栈和堆
人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中? 这里浅谈Java中的栈和堆 首先,将结论写在前面,后面再用例子加以验证. Java的栈中存储以下类型数 ...
- java中内存分配策略及堆和栈的比较
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- Java中的栈,堆,方法区和常量池
要说Java中的栈,堆,方法区和常量池就要提到HotSpot,HotSpot是Sun JDK 和 Open JDK中所带的虚拟机. (Sun JDK 和 Open JDK除了注释不同,代码实现基本上是 ...
- java中的栈(利用数组实现栈)
java中的栈(利用数组实现栈) 常见的数据结构:https://blog.csdn.net/weixin_43304253/article/details/119764275 栈的介绍 1.栈的英文 ...
随机推荐
- 浅析Java堆,栈,方法区
栈(Stack) 1.栈是线程私有的,其生命周期和线程相同. 2.每个方法在执行的时候都会开辟一个栈区,同时创建一个栈帧(Stack Frame). 3.栈帧用于存储局部变量表,操作数栈,动态链接和方 ...
- Android中实现轮询下载安装应用的Dialog
前言 因为有涉及到静默安装,主要是针对已经root的设备,应需求,是在ARM的主板上开发的,所以对于常规手机仅能做到轮询下载,做不到静默安装. 效果图 用的鸿洋大神的百分比布局,各个分辨率都完美适配, ...
- java虚拟机栈 相关操作
针对JVM虚拟栈 和栈帧的操作 虚拟机栈: 栈元素是栈帧.方法调用,栈帧入栈,反之出栈. 栈帧:一个方法的运行空间. 1.局部变量表:方法定义的局部变量.方法的参数存在该表. 实例方法中有个隐含参数“ ...
- 201871010119-帖佼佼《面向对象程序设计(java)》第十周学习总结
博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.co ...
- minicom配置1500000波特率
背景 项目需求,得用1500000波特率进行,即1.5M的波特率进行串口通信. 最开始以为minicom不支持,因为第一眼在配置界面的选项中没看见.后来发现其实是支持的 方式一 启动时带参数 -b 1 ...
- Github挂载大文件解决方案
正常情况下,我们上传代码之类的文本文件,都不会太大,可以直接通过[Upload Files]选项直接上传. 但是这样的操作仅限文件大小在25MB以内. 如果你选择的文件超过25MB,那么Github会 ...
- 基于Postman中的报错
Postman中的报错: Could not get any response 错误 Could not get any response There was an error connecting ...
- Scrcpy用电脑控制Android手机(支持Windows/macOS/Linux)
一.scrcpy简介 注意:拼写是scrcpy,非Python爬虫框架Scrapy. scrcpy可以通过adb调试的方式来将手机屏幕投到电脑上,并可以通过电脑控制您的Android设备.它可以通过U ...
- Hive脚本中切勿使用/**/注释
Hive脚本中切勿使用/**/注释 Hive脚本的注释目前好像只有 -- ,我之前在做初版数据的时候 使用NotePad++ 习惯性的有时候注释会写成 /**/ ,然后就引发了问题 脚本上传到hue, ...
- WebShell代码分析溯源(五)
WebShell代码分析溯源(五) 一.一句话变形马样本 <?php $e=$_REQUEST['e'];$arr=array($_POST['POST'],);array_filter($ar ...