jvm内存管理
java虚拟机运行时的数据区域分为:堆、程序计数器、虚拟机栈、本地方法栈、方法区。
1.程序计数器
程序计数器是一块很小的内存空间,记录当前线程所执行的字节码的行号。Java虚拟机的多线程的实现是通过线程轮流切换的方式来实现,某一时刻,一个处理器智能处理一个线程中的指令。因此每个线程都有一个独立的程序计数器。如果线程执行的是一个Java方法,这个计数器记录的是正在执行的字节码的地址,如果是Native方法,这个计数器则为空。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
2.Java虚拟机栈
线程私有。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息。平时我们所说的堆栈中的栈就是指这个。局部变量表存放了编译器可知的各种基本类型、对象引用,retrunAddress类型(指向了一条字节码指令的地址)。64位长度的long和double类型的数据会占用2个局部变量空间,其余仅占用一个。
在Java虚拟机规范中,对这个区域规定了两种异常情况:如果线程请求的深度大于虚拟机所容许的深度,将抛出StackOverflowError一场:如果虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存时会抛出OutofMemoryError异常。
3.本地方法栈
本地方法栈跟与虚拟机栈发挥的作用非常相似,只不过是执行的Native方法,不过有的虚拟机实现可以把二者归并在一起。
4.Java堆
Java堆是所有线程所共享的一块内存区域,此内存区域的唯一目的是存放对象实例,几乎所有的对象实例以及数组都要在堆上分配。
Java堆是垃圾收集器管理的主要区域。现在收集器采用的收集方法基本上是分代收集的方法。Java堆还可分为:新生代和老年代。
5.方法区
是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、敞亮、静态变量、即时编译器编译后的代码等数据。
运行时常量池是方法区的一部分。
当然还有直接内存,不在java虚拟机的范围内。
Jvm中对象的访问
举一个简单的例子
Object obj = new Object();
Object obj创建一个引用,需要存储到虚拟机栈中,而new Object需要存储到堆中,在Java堆中还必须包含能查找到此对象类型数据(如对象类型、父类、实现的接口、方法等)的地址信息,需要保存到方法区中。
浙公网安备 33010602011771号