frame中src怎么设置成一个变量_如何给女朋友讲明白:Java 中 Stack(栈) 与 Heap(堆)...

6d898007ae71a71359e885dd90197577.png

背景

Java 中 Stack(栈) 与 Heap(堆) 是面试中被经常问到的一个话题。

有没有对 Java 中 Stack(栈) 与 Heap(堆) 烂熟于心的童鞋,请举手!!!(怎么没人举手…)

这个时候蜗牛哥的对象弱弱的举起了小手(这个对象不是 new 出来的哈)

女朋友:牛哥,谁要怼咱呀?我要不要先打个摇摇灵?

蜗牛哥:Heap(堆) 与 Stack(栈) 是两种内存区域,不是要干架(没文化真可怕…)

蜗牛哥:今天就来给你讲讲 Java 中 Stack(栈) 与 Heap(堆) 到底是什么?

女朋友:好呀,好呀,搞明白了堆与栈,我是不是就是 Java 高级工程师了?

蜗牛哥:有牛哥在,你还怕搞不明白???

女朋友:嘻嘻,我已经拿好我的小本本准备好记笔记了

蜗牛哥:好的,那咱们这就开讲

什么是 Stack(栈)内存?

Java 中的 Stack(栈)是内存的一部分,包含方法、局部变量和引用变量。Stack(栈)内存始终以 后进先出 顺序引用。在 Stack(栈)内存中创建局部变量。

什么是 Heap(堆)内存?

Heap(堆)是包含对象的内存部分,也可能包含引用变量。实例变量在 Heap(堆)内存中创建。

Java 中的内存分配

JVM 将内存划分为以下部分。

  1. Heap(堆)
  2. Stack(栈)
  3. Code(代码)
  4. Static(静态)

这种内存划分是有效管理内存所必需的。

  • Code(代码) 内存包含所有您的字节码
  • Stack(栈) 内存包含所有方法、局部变量和引用变量。
  • Heap(堆) 内存包含对象 (也可以含有引用变量)。
  • Static(静态) 内存包含静态数据 / 方法

本地和实例变量之间的区别

变量实例被声明在类中但不包含方法内变量

class 

局部变量被定义在方法内部,包含方法参数。

public 

栈和堆之间的区别

让我们举个例子来更好地理解这一点。

考虑一下你的 main 方法调用方法 m1

public 

在 java 栈中,将创建一个 frame(栈帧)在方法 m1 中。

0258d51a2d03dd68c7fcc0b204c9faba.png

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

c22a07ad5c639bff342eff798a337aff.png

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

262b820fff6b9f9d4b6de8c241a59dd3.png

3823e078b1403dc0ceddcce083f97728.png

变量 b 和 c 也将在栈中的栈帧 m2 中创建。

public 

4a5d045a610dd303d9b19854347e2454.png

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

0224dae433f41a0527110a61581e1580.png

86604fff0d88e35829c6dc6f2dfffe88.png

现在假设我们的方法 m3 正在为类 “Account” 创建一个对象,它有两个实例变量 int p 和 int q。

Account 

这是方法 m3 的代码

public void m3(){
	Account ref = new Account();
	// more code
}

语句 new Account() 将在堆中创建一个 Account 对象。

3fa30b13667bc97dd452457b1b7193aa.png

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

f672ffe4f75b30cee4d7284ab2cbcecc.png

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

f4c7cd8f354d36c585ef2782eca8dd53.png

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

98e840a24af00442f1076145a06112a4.png

方法 m3 的栈将被刷新

1bf8d603be58857857281c532799e140.png

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

b504c86f2c20ca728834255af3f1eeb8.png

方法 m2 完成执行后。它将从堆栈弹出,其所有变量将被刷新,不再可用。

同样对于方法 m1。

最终,控制流程将返回程序的起始点。通常,就是 “main” 方法。

如果对象有一个引用作为其实例变量怎么办?

public 

在这种情况下,引用变量 “child” 将在堆中创建,而堆又将指向其对象,如下图所示。

f806c6a72c613ba94bc2d6f31b3421d7.png

总结一下:

  • 调用方法时,会在栈顶部创建一个栈帧。
  • 一旦方法完成执行,控制流将返回到调用方法,并刷新其相应的栈帧。
  • 在栈中创建局部变量
  • 实例变量在堆中创建并且是它们所属对象的一部分。
  • 在栈中创建引用变量。

“不积跬步,无以至千里”,希望未来的你能:有梦为马 随处可栖!加油,少年!


5e5be70a9a22c66d99221d1e3b5f54d9.png
这个对象到底如何才能new出来?在线等
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值