--reference Java Heap Memory vs Stack Memory Difference

在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有什么异同,以及和数据结构中的堆栈有何关系?

一、Java 堆存储空间

堆内存(堆存储空间)会在Java运行时分配给对象(Object)或者JRE的类。只要我们创建了一个对象,那么在堆中肯定会分配一块存储空间给这个对象。而我们熟知的Java垃圾回收就是在堆存储空间上进行的,用以释放那些没有任何引用指向自身的对象。任何在堆中分配的对象都有全局访问权限,而且可以从应用的任何地方被引用。

二、Java 栈存储空间

Java 栈存储空间用来供线程执行时使用。栈空间中包含特别的变量如:短生命周期和指向其他在堆中对象的引用。这里栈存储空间满足后进先出的顺序。当一个函数被调用时,会在栈中分配一块新的存储空间,用来存放函数的基本数据(【Java心得总结一】Java基本类型和包装类型解析)以及在函数中对其它对象的引用。一旦函数执行结束,存储空间就会被释放供下一个函数使用。

栈存储空间远远小于堆存储空间

三、举例

Memory.java

 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会为主函数线程分配栈存储空间。
  2. 我们在第二行创建了基本数据类型,所以它会被存储在主函数线程的栈存储空间;
  3. 因为我们在第三行创建了Object对象,它会在堆中被创建,并且栈空间中保存有指向它的引用。同理第四行创建Memory对象。
  4. 当我们在main()主函数第五行调用foo()函数时,在栈空间顶部会分配一块空间给foo()函数使用。因为Java是值传递(Java 为值传递而不是引用传递),在foo函数第六行中会有一个新的引用被创建指向堆中的Object对象
  5. 在第7行创建了一个字符串,它会被放在堆空间的字符串池中(String Poll),而且在栈空间中会保存一个指向它的引用
  6. 在第8行foo函数执行完毕,此时其栈空间会被释放
  7. 在第9行main函数执行完毕,栈中分配给main函数的空间会被释放。同时程序也在这一行执行完毕,因此Java运行时(Java Runtime)会释放所有内存空间并且终止程序的执行。

四、堆栈异同

  1. 堆存储空间可以被应用的任何部分使用,然而栈存储空间只能被对应的执行线程使用
  2. 一旦对象被建立,那么就会在堆中分配一段存储空间而栈空间中保留有对它的引用。栈空间中仅仅保存基本数据类型和指向堆中对象的引用变量
  3. 堆中存储的对象可以被全局访问,然而栈中存储的变量不能被其它线程(函数)访问
  4. 栈中的内存管理采用先进后出的(LIFO)的方式,然而在堆中内存管理会更为复杂,因为堆中的对象可以被全局使用。对存储空间被分为Young-Generation,Old-Generation等,这个我会在之后总结
  5. 栈存储空间是短生命周期的,然而堆存储要长的多
  6. 利用-Xms和-Xmx来指明JVM的堆初始空间和最大空间,利用-Xss来定义栈空间大小
  7. 当栈空间满了,Java运行时会抛出 java.lang.StackOverFlowError ,然而堆空间满了,抛出的是 java.lang.OutOfMemoryError: Java Heap Space 错误
  8. 栈空间相比较于堆空间是非常小的,又因为栈中使用最简单的先进后出(LIFO)原则,它是远远快于堆的。

Java 堆内存与栈内存异同(Java Heap Memory vs Stack Memory Difference)的更多相关文章

  1. Java堆空间Vs栈内存

    之前我写了几篇有关Java垃圾收集的文章之后,我收到了很多电子邮件,请求解释Java堆空间,Java栈内存,Java中的内存分配以及它们之间的区别. 您可能在Java,Java EE书籍和教程中看到很 ...

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

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

  3. Java中堆内存和栈内存详解2

    Java中堆内存和栈内存详解   Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...

  4. java堆内存和栈内存的处理

    前段时间学习二叉树在处理删除操作的时候遇到一个头疼的问题:删除节点的时候明明已经置null了可树上该节点依旧存在,还必须执行node.father.left = null;才可以删除node节点,寻找 ...

  5. java堆内存与栈内存

    java的内存分为两种,堆内存与栈内存: 堆内存用来存放数组和new的对象,比如一个文件,字节流是存放在堆中,栈内存为这个文件开辟一个索引,也就是这个文件的地址,并且保存在栈中.对象由GC处理释放内存 ...

  6. 熟悉java堆内存和栈内存和mysql的insert语句中含有id的处理

    java的堆内存和栈内存有什么区别呢? 如果mysql数据库表的id是递增的,如果没有插入id,则id自增,如果插入id,则插入什么就显示什么.

  7. 浅析JAVA中堆内存与栈内存的区别

    Java把内存划分成两种:一种是栈内存,一种是堆内存. 一.栈内存 存放基本类型的变量,对象的引用和方法调用,遵循先入后出的原则.     栈内存在函数中定义的“一些基本类型的变量和对象的引用变量”都 ...

  8. Java SE之Java中堆内存和栈内存[转/摘]

    [转/摘]1-3Java中堆内存和栈内存 注解:内存(Memory)即 内存储器,主存,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器(辅存)交换的数据. Java中把内存分为两种:栈 ...

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

    一.堆内存和栈内存 程序运行时内存分配有三种:静态存储分配,栈式存储分配,堆式存储分配 1.静态存储分配: 在程序编译时就可以确定数据目标在运行时所需要的内存,因此在编译时就为其分配固定大小的内存. ...

随机推荐

  1. 一起学微软Power BI系列-使用技巧(5)自定义PowerBI时间日期表

    1.日期函数表作用 经常使用Excel或者PowerBI,Power Pivot做报表,时间日期是一个重要的纬度,加上做一些钻取,时间日期函数表不可避免.所以今天就给大家分享一个自定义的做日期表的方法 ...

  2. 如何正确使用日志Log

    title: 如何正确使用日志Log date: 2015-01-08 12:54:46 categories: [Python] tags: [Python,log] --- 文章首发地址:http ...

  3. C# 多种方式发送邮件(附帮助类)

    因项目业务需要,需要做一个发送邮件功能,查了下资料,整了整,汇总如下,亲测可用- QQ邮箱发送邮件 #region 发送邮箱 try { MailMessage mail = new MailMess ...

  4. .NET Core采用的全新配置系统[9]: 为什么针对XML的支持不够好?如何改进?

    物理文件是我们最常用到的原始配置的载体,最佳的配置文件格式主要由三种,它们分别是JSON.XML和INI,对应的配置源类型分别是JsonConfigurationSource.XmlConfigura ...

  5. NET Core-学习笔记(四)

    经过前面分享的三篇netcore心得再加上本篇分享的知识,netcore大部分常用知识应该差不多了,接下来将不会按照章节整合一起分享,因为涉及到的东西整合到一起篇幅太大了,所以后面分享将会按照某一个知 ...

  6. Exception in thread "main" java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V

    在学习CGlib动态代理时,遇到如下错误: Exception in thread "main" java.lang.NoSuchMethodError: org.objectwe ...

  7. APP多版本共存,服务端如何兼容?

    做过APP产品的技术人员都知道,APP应用属于一种C/S架构的,所以在做多版本兼容,升级等处理则比较麻烦,不像web应用那么容易.下面将带大家分析几种常见的情况和应对方式: 小改动或者新加功能的 这种 ...

  8. 关于CSS inline-block、BFC以及外边距合并的几个小问题

    CSS inline-block和BCF对于初学者来说,总是弄不太明白,下面记录下我在学习这块知识的过程中遇到的几个问题,供大家参考,有不足的地方,欢迎大家批评指正. 一.在什么场景下会出现外边距合并 ...

  9. atitit.管理学三大定律:彼得原理、墨菲定律、帕金森定律

    atitit.管理学三大定律:彼得原理.墨菲定律.帕金森定律 彼得原理(The Peter Principle) 1 彼得原理解决方案1 帕金森定律 2 如何理解墨菲定律2 彼得原理(The Pete ...

  10. oracle SEQUENCE 创建, 修改,删除

    oracle创建序列化: CREATE SEQUENCE seq_itv_collection            INCREMENT BY 1  -- 每次加几个              STA ...