JVM中的Stack和Heap

Stack: 是内存指令区。Java基本数据类型,Java指令代码,常量都保存在stack中,方法是指令也保存在stack中。

由于stack是内存是顺序分配,而且定长,不存在内存回收问题。存取速度快。

Heap: 是内存数据区。管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。而对象实例在Heap 中分配好以后,需要在Stack中保存一个4字节的Heap 内存地址,用来定位该对象实例在Heap 中的位置,便于找到该对象实例。

而Heap 则是随机分配内存,不定长度,存在内存分配和回收的问题;因此在JVM中另有一个GC进程,定期扫描Heap ,它根据Stack中保存的4字节对象地址扫描Heap ,定位Heap 中这些对象,进行一些优化(例如合并空闲内存块什么的),并且假设Heap 中没有扫描到的区域都是空闲的,统统refresh(实际上是把Stack中丢失了对象地址的无用对象清除了),这就是垃圾收集的过程;

非静态方法和静态方法的区别:

非静态方法有一个和静态方法很重大的不同:非静态方法有一个隐含的传入参数,该参数是JVM给它的,和我们怎么写代码无关,这个隐含的参数就是对象实例在Stack中的地址指针。因此非静态方法(在Stack中的指令代码)总是可以找到自己的专用数据(在Heap 中的对象属性值)。当然非静态方法也必须获得该隐含参数,因此非静态方法在调用前,必须先new一个对象实例,获得Stack中的地址指针,否则JVM将无法将隐含参数传给非静态方法。

静态方法无此隐含参数,因此也不需要new对象,只要class文件被ClassLoader load进入JVM的Stack,该静态方法即可被调用。当然此时静态方法是存取不到Heap 中的对象属性的。

总结一下该过程:当一个class文件被ClassLoader load进入JVM后,方法指令保存在Stack中,此时Heap 区没有数据。然后程序技术器开始执行指令,如果是静态方法,直接依次执行指令代码,当然此时指令代码是不能访问Heap 数据区的;如果是非静态方法,由于隐含参数没有值,会报错。因此在非静态方法执行前,要先new对象,在Heap 中分配数据,并把Stack中的地址指针交给非静态方法,这样程序技术器依次执行指令,而指令代码此时能够访问到Heap 数据区了。

静态属性和动态属性

前面提到对象实例以及动态属性都是保存在Heap 中的,而Heap 必须通过Stack中的地址指针才能够被指令(类的方法)访问到。因此可以推断出:静态属性是保存在Stack中的,而不同于动态属性保存在Heap 中。正因为都是在Stack中,而Stack中指令和数据都是定长的,因此很容易算出偏移量,也因此不管什么指令(类的方法),都可以访问到类的静态属性。也正因为静态属性被保存在Stack中,所以具有了全局属性。

在JVM中,静态属性保存在Stack指令内存区,动态属性保存在Heap数据内存区。

时间: 2024-07-28 17:36:38

JVM中的Stack和Heap的相关文章

Java虚拟机JVM总结(一)JVM运行原理及JVM中的Stack和Heap的实现过程

Java语言写的源程序通过Java编译器,编译成与平台无关的'字节码程序'(.class文件,也就是0,1二进制程序),然后在OS之上的Java解释器中解释执行,而JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器. 一.JVM原理 1.JVM简介: JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器.它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行java的字节码程序. java编译器只要面向JVM,生成JVM能理解

深入Java虚拟机:JVM中的Stack和Heap

转自:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html —————————————————————————————————————————————— 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题. 一般,JVM的内存分为两部分:Stack和Heap. Stack(栈)是JVM的内

jvm的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集(转)

深入Java虚拟机:JVM中的Stack和Heap(转自:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题. 一般,JVM的内存分为两部分:Stack和Heap. Stack(栈)是JVM的内存指令区.Stack管理很简单,push

JAVA虚拟机中的堆内存Heap与栈内存Stack

原文链接:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html 深入Java虚拟机:JVM中的Stack和Heap 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题. 一般,JVM的内存分为两部分:Stack和Heap. Stack(栈)是JVM的内存指令区.Stack管理很简单,pus

JVM运行原理及Stack和Heap的实现过程

Java语言写的源程序通过Java编译器,编译成与平台无关的‘字节码程序’(.class文件,也就是0,1二进制程序),然后在OS之上的Java解释器中解释执行,而JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器. 一.JVM原理 1.JVM简介: JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器.它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行java的字节码程序. java编译器只要面向JVM,生成JVM能理解

java中堆栈(stack)和堆(heap)

原文地址:http://blog.csdn.net/jerryao/article/details/874101 1.内存分配策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. (1)静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求 (2)栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个

java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)

(1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为 它们都会导致编译程序无法计算准确的存储空间需求. 栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存 储分配相反,在栈式存储方案中,程序对

JVM -Xss调整Stack Space的大小 【转】

Java程序中,每个线程都有自己的Stack Space.这个Stack Space不是来自Heap的分配.所以Stack Space的大小不会受到-Xmx和-Xms的影响,这2个JVM参数仅仅是影响Heap的大小. Stack Space用来做方法的递归调用时压入Stack Frame.所以当递归调用太深的时候,就有可能耗尽Stack Space,爆出StackOverflow的错误.Stack Space的大小随着OS,JVM以及环境变量的大小而发生变化.一般说来默认的大小是512K.在64

JVM中可生成的最大Thread数量

最近想测试下Openfire下的最大并发数,需要开大量线程来模拟客户端.对于一个JVM实例到底能开多少个线程一直心存疑惑,所以打算实际测试下,简单google了把,找到影响线程数量的因素有下面几个: -Xms intial java heap size -Xmx maximum java heap size -Xss the stack size for each thread 系统限制 系统最大可开线程数 测试程序如下: import java.util.concurrent.atomic.A