java虚拟机基本结构
包括:方法区、Java堆、Java栈、本地方法区、程序计数器等。
参考《输入理解Java虚拟机》,如下图:
其中方法区和堆是由所有线程共享,而Java栈、本地方法区、程序计数器是线程私有。
java 堆
是与应用程序最相关的区域,几乎所有的对象都在堆上创建。java堆最常见的结构是将其分为新生代和老年代,新生代又分为eden区和survivor区。survivor区又分为大小相等的from区和to区。
java -Xmx(-Xms)32m class [args...] //指定堆的最大最小可用内存32m
java -XX:+PrintGC SimpleArgs //执行SimpleArgs.class并打印GC日志
java 栈
java栈是和线程密切相关的私有内存空间,在java栈中,每一次函数调用就会有一个对应栈帧被压入java栈。当函数返回的时候,栈帧从java栈中被弹出。函数返回有两种方式:正常return和抛出异常。
每一个栈帧中包含:局部变量表、操作数栈、帧数据区等几个部分。
java -Xss256k class [args...] //指定线程最大栈空间256k
-
局部变量表
保存函数的参数及局部变量。局部变量表的槽位是可以复用的,当局部变量过了其作用域,其作用域后声明的局部变量会有可能复用过期的局部变量的槽位。
public static void method1() {
int a=0;
int b=0;
}
index name
0 this
1 a
2 b
该函数在运行中最大局部变量为3字,实例方法的第一个局部变量都是this引用。
public static void method1() {
{
int a=0;
}
int b=0;
}
index name
0 this
1 a
1 b
该函数在运行中最大局部变量为2字,b复用了a的槽位。
操作数栈
保存计算的中间结果,操作数栈也是一个先进后出的数据结构。帧数据区
包括常量池指针、正常方法返回和异常处理等。帧数据区包含异常处理表:
Exception table
from to target type
4 16 19 any
表示在字节码偏移量为4-16字节可能抛出异常,遇到异常则跳转到字节码偏移19处执行。
java 方法区
在JDK1.6、JDK1.7中,方法区可以理解为永久区(Perm)。
java -XX:PermSize class [args...] //设置初始永久区大小
java -XX:MaxPermSize class [args...] //设置最大永久区大小,默认为64MB
在JDK1.8中永久区被移除,取而代之的是元数据区,这是一块堆外直接内存,使用系统资源。
java -XX:MaxMetaspaceSize class [args...] //设置最大永久区大小,默认可以耗尽系统内存资源