JVM虚拟机分析—1.关于java运行时内存区域分配的描述
一.内存区域的描述
先上图:
在JAVA运行的时候会将自己管理的内存分配成如上的不同区域以供java使用。以下分别介绍以下区域的划分以及其存储的东西。
- METHOD AREA(方法区)
方法区是各线程共享的区域,它存储的是虚拟机加载的类的信息(类名,访问修饰符等),常量,静态变量,方法代码等(通过-XX:MaxPermSize
可以设置该区域的上限)
应该该区域的对象一般来说不会改变也不会被回收,因此被称为“永生代”。 -
HEAP(堆)
堆存储的是几乎所有的实例对象,几乎所有的对象都在HEAP上分配内存,该区域是垃圾回收的主要区域,也被称为“GC堆”。(可以通过-Xmx
与-Xms
来设置该区域的最大内存与最小内存)
该区域是线程共享的。
3.JAVA STACK(虚拟机栈)
该区域线程私有,随线程生而生,随线程死而死。存储的是线程中java方法执行时的内存模型。关于方法执行时的栈帧描述可以查看阮一峰老师的这篇文章:STACK
可以这样理解,方法内的所有局部变量都存在该区域里面。
4.NATIVE METHOD STACK(本地方法栈)
本地方法使用的栈内存区域(例如NATIVE的原生方法)
5.PROGRAM COUNTER REGISTER(程序计数器)
该区域存储的是当前执行线程所执行到代码的行号,这样的话在切换线程的时候就知道该线程执行到哪里了,因此是线程私有的。二.对象在HEAP中存储的描述
对象会在HEAP中进行生成,一般来说对象在内存中的分布可以分为三块部分:1.对象头 2实例数据 3对齐填充。
对象头存储的是对象自己运行时的数据,例如哈希码,GC分代年龄,锁的状态标识等等。实例数据则是对象的具体数据例如实例成员变量等等。对齐填充起占位符作用,不一定要有。
当java程序通过方法栈中的reference数据来引用HEAP上的对象,而如此访问有两种形式:
1.句柄形式
2.直接指针访问
这里有这篇文章可以查看一下两种形式,图即引用自该文章