前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java堆空间Vs栈内存

Java堆空间Vs栈内存

作者头像
淡定的蜗牛
修改2019-11-04 14:42:51
1.2K0
修改2019-11-04 14:42:51
举报
文章被收录于专栏:Java知己

之前我写了几篇有关Java垃圾收集的文章之后,我收到了很多电子邮件,请求解释Java堆空间Java栈内存Java中的内存分配以及它们之间的区别。

在这里插入图片描述
在这里插入图片描述

您可能在Java,Java EE书籍和教程中看到很多有关堆和变量内存的参考,但是几乎没有就程序而言完全解释堆和栈的内存分配的。

Java堆空间

Java运行时使用Java堆空间为对象和JRE类分配内存。每当我们创建任何对象时,它总是在堆空间中创建。

垃圾回收在堆内存上运行以释放没有任何引用的对象使用的内存。在堆空间中创建的任何对象都具有访问权限,并且可以从应用程序的任何位置进行引用。

Java栈内存

Java Stack内存用于执行线程。它们包含短期的方法特定值,以及从该方法引用的对堆中其他对象的引用。

每当调用方法时,都会在磁盘存储中创建一个新块,以容纳该方法的本地原始值并引用该方法中的其他对象。

方法结束后,该块将立即立即变为未使用状态,用作下一个方法使用。

与堆内存分配,栈内存的大小要小一点。

Java程序中的堆空间和栈内存分配

让我们用一个简单的程序来了解堆和交替的内存使用情况。

代码语言:txt
复制
package com.journaldev.test;

public class Memory {

	public static void main(String[] args) { // Line 1
		int i=1; // Line 2
		Object obj = new Object(); // Line 3
		Memory mem = new Memory(); // Line 4
		mem.foo(obj); // Line 5
	} // Line 9

	private void foo(Object param) { // Line 6
		String str = param.toString(); //// Line 7
		System.out.println(str);
	} // Line 8

}

下图显示了与上述程序有关的堆空间和栈内存,以及如何将其用作存储原始,对象和引用变量。

在这里插入图片描述
在这里插入图片描述

让我们看一下程序的执行步骤。

  • 一旦运行程序,它将所有运行时类加载到堆空间中。在第1行找到main()方法后,Java Runtime创建的堆内存将被main()线程中方法使用。
  • 我们在第2行创建原始局部变量,因此将其创建并存储在main()方法的栈内存中。
  • 由于我们在第3行中创建了一个对象,因此将在堆内存中创建该对象,并且栈内存块包含该对象的引用。在第4行中创建内存对象时,也会发生类似的过程。
  • 现在,当我们在第5行调用foo()方法时,将在栈内存顶部创建一个块,以供foo()方法使用。由于Java是按值传递的,因此在第6行的foo()变量中中创建了对Object的新引用。
  • 在第7行创建一个字符串,该字符串进入堆空间的“字符串池”,并在foo()最小空间中创建引用。
  • foo()方法在第8行终止,这时分配给中foo()的栈内存块被释放。
  • 在第9行中main()方法终止,并为main()方法创建的栈内存被销毁。程序同时此行结束,因此Java Runtime释放了所有内存并结束了程序的执行。

如果您对Java编码技巧与实践更感兴趣,请阅读Joshua Bloch撰写的《Effective Java 中文 第三版》 ,这是值得深读的一本书。在公众号【Java知己】,后台回复:Effective Java,可以获得该书籍。

Java堆空间和栈内存之间的区别

根据以上解释,我们可以轻松得出以下堆空间和栈内存的区别。

  1. 堆内存由应用程序的所有部分使用,而堆栈内存仅由一个执行线程使用。
  2. 在内存中创建对象时,它始终存储在堆空间中,并存储到包含该对象的引用中。内存仅包含本地原始变量和堆空间中对象的引用变量。
  3. 堆中存储的对象可以分区访问,而其他线程则不能访问分区内存。
  4. 堆栈中的内存管理是以后进先出(LIFO)的方式完成的,而堆内存中的内存管理更复杂,因为它是全局使用的。
  5. 栈内存是短暂的,而堆空间是从应用程序执行的开始一直到结束。
  6. 我们可以使用-Xms-Xmx JVM选项来定义堆空间的初始值和最大值。我们可以使用-Xss定义栈内存的大小。
  7. 当栈内存已满时,Java运行时将java.lang.StackOverFlowError引发,而如果堆内存已满,则将引发java.lang.OutOfMemoryError: Java Heap Space错误。
  8. 栈内存相比于堆空间是非常小的。由于LIFO的简单性,与堆空间相比,栈内存非常快。

就Java应用程序而言,这就是Java堆空间与栈内存的全部,我希望它能在执行任何Java程序时消除您对内存分配的疑问。


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

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java堆空间
  • Java栈内存
  • Java程序中的堆空间和栈内存分配
  • Java堆空间和栈内存之间的区别
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档