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

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

Java堆空间

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

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

Java栈内存

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

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

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

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

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

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

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堆空间和栈内存之间的区别

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

  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程序时消除您对内存分配的疑问。


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

关注公众号:「Java 知己」,每天更新Java知识哦,期待你的到来!

  • 发送「Group」,与 10 万程序员一起进步。
  • 发送「面试」,领取BATJ面试资料、面试视频攻略。
  • 发送「玩转算法」,领取《玩转算法》系列视频教程。
  • 千万不要发送「1024」...

Java堆空间Vs栈内存的更多相关文章

  1. 一步步优化JVM四:决定Java堆的大小以及内存占用

    到目前为止,还没有做明确的优化工作.只是做了初始化选择工作,比如说:JVM部署模型.JVM运行环境.收集哪些垃圾回收器的信息以及需要遵守垃圾回收原则.这一步将介绍如何评估应用需要的内存大小以及Java ...

  2. Java堆空间的划分:新生代、老年代

    参考链接:Java堆空间的划分:新生代.老年代

  3. [转] Cz/C++中栈空间、堆空间,及内存区域的划分

    kevinGao, 原文地址 一个由C/C++编译的程序占用的内存分为以下几个部分: 1.栈区(stack):又编译器自动分配释放,存放函数的参数值,局部变量的值等,其操作方式类似于数据结构的栈. 2 ...

  4. Exception in thread "main" java.lang.OutOfMemoryError: Java heap space(Java堆空间内存溢出)解决方法

    http://hi.baidu.com/619195553dream/blog/item/be9f12adc1b5a3e71f17a2e9.html问题描述Exception in thread &q ...

  5. Java堆(heap)、栈(stack)和队列的区别

    Java里面Stack有两种含义: 一:数据结构 Stack,即java.util.Stack import java.util.Stack; import java.util.Iterator; i ...

  6. 解释 Java 堆空间及 GC?

    当通过 Java 命令启动 Java 进程的时候,会为它分配内存.内存的一部分用于 创建堆空间,当程序中创建对象的时候,就从对空间中分配内存.GC 是 JVM 内 部的一个进程,回收无效对象的内存用于 ...

  7. Java堆空间溢出解决方法 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

    一般通过java -jar filename.jar运行jar包,但是当运行的java程序需要较大的内存时,可能会造成堆空间溢出. 例如,加载了几个G大小的json文件,运行报错: Exception ...

  8. zz 堆空间与栈空间

    http://blog.sina.com.cn/s/blog_7321be1101013aua.htmlhttp://soft.chinabyte.com/os/51/12324551.shtmlht ...

  9. JAVA内存管理之堆内存和栈内存

    我们常常做的是将Java内存区域简单的划分为两种:堆内存和栈内存.这种划分比较粗粒度,这种划分是着眼于我们最关注的.与对象内存分配密切相关的两类内存域.其中栈内存指的是虚拟机栈,堆内存指的是java堆 ...

随机推荐

  1. 大数据学习笔记——Hbase高可用+完全分布式完整部署教程

    Hbase高可用+完全分布式完整部署教程 本篇博客承接上一篇sqoop的部署教程,将会详细介绍完全分布式并且是高可用模式下的Hbase的部署流程,废话不多说,我们直接开始! 1. 安装准备 部署Hba ...

  2. php数组去重、魔术方法、redis常用数据结构及应用场景

    一.用函数对数组进行去重的方法 1.arrau_unique函数的作用 移除数组中重复的值. 将值作为字符串进行排序,然后保留每个值第一次出现的健名,健名保留不变. 第二个参数可以选择排序方式: SO ...

  3. Test 1023 T1&T2

    T1 popust (贪心 TimeLimit: 1000MS Memory Limit: 32768KB ​ 米尔科饿了如熊,偶然发现当地一家餐馆.餐厅提供\(n\)种餐,有一个有趣的定价政策:每种 ...

  4. 建议2:注意Javascript数据类型的特殊性---(3)正确检测数据类型

    使用typeof预算符返回一个用于识别其运算数类型的字符串.对于任何变量来说,使用typeof预算符总是以字符串的形式返回一下6种类型之一 number string boolean object f ...

  5. Python复习第01天---元类底层原理

    1.通过元类限制类的名字首字母大写 if not class_name.istitle(): raise TypeError('类的名字首字母需要大写') 2. 控制类中必须要有注释 if not c ...

  6. 在Docker中跑Hadoop与镜像制作

      重复造轮子,这里使用重新打包生成一个基于Docker的Hadoop镜像:   Hadoop集群依赖的软件分别为:jdk.ssh等,所以只要这两项还有Hadoop相关打包进镜像中去即可: 配置文件准 ...

  7. 从KafkaConsumer看看Kafka(一)

      Kafka的消息模型为发布订阅模型,消息生产者将消息发布到主题(topic)中,一个或多个消费者订阅(消费)该主题消息并消费,此模型中发布到topic中的消息会被所有消费者所订阅到,先介绍Kafk ...

  8. Wonder第一期3D引擎和编辑器线下培训班报名开始啦(免费学习)

    Wonder第一次举办 针对3D底层技术的 线下培训班,免费学习,请大家多多支持-感谢- 培训地点 成都 开课时间 报名满5人开课. 报名方式 加QQ群:732861508 备注请写:报名培训 老师介 ...

  9. 远程桌面MATLAB启动失败问题解决

    博客:博客园 | CSDN | blog 远程桌面打开MATLAB会报错,解决办法,打开matlab的licenses路径,如matlab/R2017b/licenses/,路径下存有license文 ...

  10. Mysql基于Mysql Cluster+MysqlRouter的集群部署方案

    http://note.youdao.com/noteshare?id=a61c4a6ff2b76e5305430eb66eb116e2&sub=4B4B6E8D0E2849F9B0DFB67 ...