原来JVM中的堆栈TM这么简单!

二话不说先上图!

好,也许你已经懂了,如果想更懂,请看今天的正文!


以下是正文:

也许你会在网上查询到很多有关栈啊,堆啊的很多内容,或者一些java ee的书上或者一些教程里。但似乎很少有一个对于stack和heap的完整的详细的解释。

Java Heap Memory

堆内存(heap memory)是被用来在runtime的时候给对象和jre的那些class分配内存的。注意是runtime的时候。不管你何时创建对象,创建任何一个对象,这些对象都是被创建在了heap空间里的。那个我们熟悉的gc(垃圾回收站)负责把那些不再被引用(reference)的对象从heap memory中清理掉,这也是gc的职责所在。在heap空间里创建的任何对象都是全局访问的。可以被应用程序的任何地方引用。

Java Stack Memory

java里的stack内存(stack memory)是被用来线程的执行的。也就是stack是线程级别的。而heap是对象级别的。这个stack里边包含了方法里边那些定义的值,这些值随着一次方法执行完毕后就消失了;还包含了引用地址。这个引用地址就是对存放在heap memory中的一个链接。你可以理解为关系数据库里边的外键,nosql中的外链。总之你理解就行。stack memory由于她是个stack结构。所以呢,他也遵循LIFO,就是后进先出的顺序。一个方法不论什么时候被调用,一个针对该方法的全新的block就会在stack memory里被创建,用来存储这个方法里的本地基本类型的值以及这个方法对其他对象的引用地址。一旦方法执行结束,这个block的状态就变为unused了,就是变为了空闲状态,就变为available了。宣布单身了,等着下一个method来用她。stack memory的size相比heap memory的size要小得多。

现在就让我们上一个simple program来更好的理解一下堆栈memory。

Memory.java public class Memory { public static void main(String[] args) { // Line1 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 }

下面这个图就展示了在上面这个程序中的stack和heap memory的存储和引用关系。堆栈怎么被用来存储基本类型值(primitive value)以及对象以及对象的引用。

接下来我们就一步步的来看上面的那个program的执行情况。

• 一旦我们运行了这个程序,它就会把所有的runtime class load 到 heap空间。当main()方法在line1那个地方被发现后,Java Runtime就会创建stack memory给main()方法这个线程来用。

• 在line2那个地方,我们创建了一个primitive(基本类型)的局部变量,这个变量自然是被存储到了main()的stack memory里的。

• 在line3那个位置,我们创建了一个对象,按照前面说的,这个对象自然是存储在heap memory里边的,并且在stack memory里边也有个这个对象的引用地址被存储了进去。line4的对象创建过程和line3是一样的。

• 现在我们来到了line5这个地方,这一行我们调用了foo()方法,这时候一个block在stack的顶部被创建,这个block现在专门为foo()方法服务。由于java是按值传递,所以在line6那个位置一个新的对象引用就会在foo() 方法的stack block中被创建。

• 在line7那个位置,一个字符串被创建,这个串是在heap空间的string池(String Pool)中。并且对这个string对象的引用自然也在foo()方法的stack空间里被创建了。

• 在line8那个地方foo()方法就被终止了,在方法结束的时候,在stack中为foo()分配的那个block重新变回空窗期,宣布available了。

• 在line9那个地方,main()方法也要结束了。自然为main()创建的stack memory就会被destory掉了。自此,Java Runtime 释放所有的memory然后结束程序的执行!

heap memory与stack memory的区别

基于上面的那一堆解释,我们现在可以很轻松的总结出以下不同之处:

1 heap用在一个application的很多地方,但stack memory只用于一个线程的执行。前者是对象级别,后者是线程级别。

2 只要是对象的创建,都是被存储到heap space中,同时stack中有这个对象的引用地址。stack memory中只包含基本类型变量和存储在heap space中的对象的引用变量。

3 存储在heap中的对象是全局都可以访问的,然而stack memory不能被其他线程访问。

4 stack 的内存管理是使用LIFO的,然而heap的内存管理要更复杂,因为heap是被全局使用的。因此heap memory被分为Young-Generation,Old-Generation等等,有关这个你可以去了解下java的

gc(垃圾回收)机制。

5 stack memory是短命的,然而heap memory则是application运行的整个生命周期都有他,直到application结束掉。

6 我们使用-Xms-Xmx jam 参数来定义heap memory的启动size和最大size。stack memory的size则是使用-Xss。

7 当stack memory满了,那么Java runtime就会抛出一个java.lang.StackOverFlowError的异常。当heap memory 满了,则会抛出java.lang.OutOfMemoryError: Java Heap Space error.

8 stack memory相比heap memory来说是非常小的。另外由于内存分配比较简单(LIFO),stack memory相比heap memory来说是非常快的。

以上就是有关Stack vs Heap Memory的全部内容,希望这篇文章能够帮到你。有什么问题欢迎在评论区讨论。


附:以下是我在网上找到的一些图片,让你对stack和heap有更直观的印象。

Stack : – local variables Heap : – instance variables – static variables – objects

原文发布于微信公众号 - ImportSource(importsource)

原文发表时间:2016-05-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏python3

python类(class)

类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例,把所有相似的功能都封装到一个类里,最理...

11730
来自专栏欧阳大哥的轮子

深入解构iOS系统下的全局对象和初始化函数

事件源于接入了一个第三方库导致应用出现了大量的crash记录,很奇怪的是这么多的crash居然没有收到用户的反馈信息! 在这个过程中每个崩溃栈的信息都明确的指向...

24320
来自专栏Java开发者杂谈

Python(1):入门

安装:    在linux中一般都自带有python2.7的版本,如果想升级python到最新的版本可以参考其他博客(http://www.cnblogs.c...

38480
来自专栏java一日一条

Java内存管理原理及内存区域详解

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干不同的数据区域,这些区域都有各自的用途以及创建和销毁的时间。Java虚拟机所管理的内存将会包...

5510
来自专栏不止是前端

深入Node

370130
来自专栏CodingToDie

java 代理

java 代理 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额...

36740
来自专栏蓝天

C语言编程程序的内存如何布局

C语言程序在内存中各个段的组成   C语言程序连接过程中的特性和常见错误   C语言程序的运行方式   一:C语言程序的存储区域   由C语言代码(文本...

25220
来自专栏IMWeb前端团队

Promise接口实现之jQuery 的deferred对象

本文作者:IMWeb json 原文出处:IMWeb社区 未经同意,禁止转载 Promise是什么? 我们知道JavaScript是单线程,如果遇到某...

199100
来自专栏java系列博客

深入理解Java内存模型(二)——重排序

23140
来自专栏zhisheng

Windows 64位下安装Redis超详细教程

Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(...

418120

扫码关注云+社区

领取腾讯云代金券