java虚拟机的基本结构

java虚拟机的参数设置
java [虚拟机参数] class [main()函数参数]
实例:
public class SimpleArgs {
public static void main(String[] args) {
for(int i=0;i<args.length;i++) {
System.out.println("args"+(i+1)+":"+args[i]);
}
System.out.println("-Xmx"+Runtime.getRuntime().maxMemory()/1000/1000+"M");
}
}
认识java堆
根据垃圾回收机制的不同,java堆可能有不同的结构,最常见的结构如下:
认识java栈
java虚拟机最大栈空间可以用参数
-Xss
指定,如果局部变量表的函数参数和局部变量增多,函数的嵌套层次将变少,帧栈和函数调用如下图所示:
栈上分配与逃逸分析
非逃逸对象有可能分配到栈上,好处是在函数调用结束后自行销毁,不需要垃圾回收器的介入,所以栈上分配速度快,(但是栈空间比较小,大对象不合适在栈上分配)。
// 对象User u 是类的成员,该字段可能被任何线程访问,因此属于逃逸对象
private static User u;
public static void alloc() {
u = new User();
u.id = 5;
u.name = "haward";
}
// 下面的为非逃逸对象
public static void alloc() {
User u = new User();
u.id = 5;
u.name = "haward";
}
认识局部变量表
利用
jclasslib
工具分析函数的局部变量信息(打开class字节码)
源码为
public class Main {
public static void main(String[] args) {
TestClass testClass = new TestClass();
testClass.localvar1();
testClass.localvar2();
}
}
class TestClass {
// 局部变量a和b都作用到函数末尾,b无法复用a所在的槽位
public void localvar1() {
int a = 0;
System.out.println(a);
int b = 0;
}
// 局部变量a在19行时候不在有效,b复用a所在的槽位
public void localvar2() {
{
int a = 0;
System.out.println(a);
}
int b = 0;
}
}
认识方法区
方法区是一块所有线程共享的内存区域,用于保存系统类的信息,比如类的字段、方法、常量池等。方法区的大小决定了系统可以保存多少个类,可以使用参数
-XX:MaxPermSize
和
-XX:PermSize
指定大小
参考:
《实战java虚拟机》