Java堆空间Vs栈内存

之前我写了几篇有关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」...

原文地址:https://www.cnblogs.com/java-friend/p/11790922.html

时间: 2024-09-30 19:25:24

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

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

原文:http://blog.csdn.net/zhoutao198712/article/details/7783070 到目前为止,还没有做明确的优化工作.只是做了初始化选择工作,比如说:JVM部署模型.JVM运行环境.收集哪些垃圾回收器的信息以及需要遵守垃圾回收原则.这一步将介绍如何评估应用需要的内存大小以及Java堆大小.首先需要判断出应用存活的数据的大小,存活数据的大小是决定配置应用需要的Java堆大小的重要条件,也能够决定是否需要重新审视一下应用的内存需求或者修改应用程序以满足内存需

程序的内存空间 堆空间和栈空间的区别

一个由C/C++编译的程序占用的内存分为以下几个部分: 1.栈区(stack): 由编译器自动分配释放,其操作方式类似于数据结构的栈. 用于存放函数的参数值,用户程序临时创建的局部变量等,即函数括号"{}"中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量).除此之外,在函数被调用时,其参数也会被压入发起调用的进程栈中,等到调用结束后,函数的返回值也会被存放回栈中. 由于栈的后进先出特点,所以栈特别方便用来保存/恢复调用现场.从这个意义上讲,可以把栈看成

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

http://hi.baidu.com/619195553dream/blog/item/be9f12adc1b5a3e71f17a2e9.html问题描述Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 解决方案[转] 一直都知道可以设置jvm heap大小,一直用eclipse写/调试java程序.一直用命令行or console加参数跑程序.现象:在eclipse的配置文件eclipse.

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

我们常常做的是将Java内存区域简单的划分为两种:堆内存和栈内存.这种划分比较粗粒度,这种划分是着眼于我们最关注的.与对象内存分配密切相关的两类内存域.其中栈内存指的是虚拟机栈,堆内存指的是java堆. 1.栈内存,即虚拟机栈.每个方法被执行的时候都会同时创建一个栈帧,用来存储局部变量,操作栈,动态链接,方法出口等信息.局部变量包括各种基本类型的变量和对象的引用变量都是在方法的栈内存中分配.其中,64位长度的long和double类型的数据占用2个局部变量的空间,其他数据类型只占用1个.局部变量

JAVA堆内存和栈内存初步了解

一.堆内存和栈内存 程序运行时内存分配有三种:静态存储分配,栈式存储分配,堆式存储分配 1.静态存储分配: 在程序编译时就可以确定数据目标在运行时所需要的内存,因此在编译时就为其分配固定大小的内存. 这种分配策略不允许代码中有可变数据结构,比如可变数组,嵌套循环结构或者递归,否则无法计算所需要的内存空间. 2.栈式存储分配: 在程序编译时无法计算所需要内存,只有在程序运行时才可以确定数据目标所需要的内存. 要求程序运行到一个模块的入口处,就可以计算该模块数据区所需要的内存空间. 栈内存是由编译器

Java堆内存的10个要点

当我开始学习Java编程时,我不知道什么是堆内存或堆空间,我甚至不知道当对象创建时,它们被放在了哪里.当我开始正式写一些程序后,我会经常遇到java.lang.outOfMemoryError的报错,之后我才开始关注什么是堆内存或者说堆空间(heap space).对大多数程序员都经历过这样的过程,因为学习一种语言是非常容易来的,但是学习基础是非常难的,因为没有什么特定的流程让你学习编程的每个基础,使你发觉编程的秘诀.对于程序员来说,知道堆空间,设置堆空间,处理堆空间的outOfMemoryEr

matlab中增加Java VM 的堆空间(解决xml_io_tools出现的OutOfMemory问题)

今天用MATLAB写程序,调用了xml_io_tools(很赞的一个xml读写工具包)中的函数,但是由于我要书写的文件比较大,5m左右,运行时不知道xml_io_tools中的哪一块超出了java中的内存限制,于是就来研究下怎么增加matlab中Java VM的堆空间,首先用英文在墙外搜了半天,google搜出来的前几条都是使用Jconsole来分配空间的,但是需要下载相应的matlab的版本的JDK的,中间各种曲折,详见文尾,最后放弃治疗的用中文搜了一下,发现早就有了官方的解答了,汗,将文章复

JavaScript 数据结构与算法之美 - 栈内存与堆内存 、浅拷贝与深拷贝

前言 想写好前端,先练好内功. 栈内存与堆内存 .浅拷贝与深拷贝,可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算法和方便以后复习. 栈 定义 后进者先出,先进者后出,简称 后进先出(LIFO),这就是典型的栈结构. 新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端就叫栈底. 在栈里,新元素都靠近栈顶,旧元素都接近栈底. 从栈的操作特性来看,是一种 操作受限的线性表,只允许在

java工程积累——如何处理Tomcat内存溢出

在项目的部署中,我们设置不当,有时会常常遇到一个bug,就是内存溢出,而在百般调试,释放资源之后,却还是没有解决,这时,不要着急,我们静下心来,在数据量,代码量都不多情况下,并且不是很经常出现这bug时,我们要进行一下小小的总结,来处理这类事件的发生! 错误 我们先看,内存溢出的提示,一般会有三种,我们一一看看: 这里根据平时遇到的情况和相关资料进行一个总结.常见的一般会有下面三种情况: 1.OutOfMemoryError: Java heap space 2.OutOfMemoryError