JVM-1. 基本结构
Java虚拟机的基本结构
java虚拟机架构
启动Java虚拟机
java [-option] class [args...]
- Options: Java虚拟机启动参数
- Class: 带有main方法的Java类。
- args: main方法的参数
Java堆
几乎所有的对象都在堆中。
根据垃圾回收机制的不同,Java堆可能有不同的结构,最常见的是分为新生代和老年代,新生代存放新生对象或年龄不大的对象,老年代存放年龄不大的对象。新生代可能分为eden去、s0和s1区,s0和s1成为from和to区域,他们是两个大小相等,可以互换角色的内存空间,
堆、方法区、栈图
Java方法如何执行的 栈
执行方法-->入栈
方法执行结束-->出栈
栈上分配
栈上分配是JVM优化技术,基本思想:线程私有的对象打散分配到栈空间,而不是堆空间。好处是:函数调用结束后自行销毁,不需要垃圾回收器介入。
逃逸分析:判断变量在方法调用结束后是否被方法外的变量引用,如果被引用则逃逸成功,不可以分配到栈中。如:
private static BigDecimal price;
static void fun()
{
BigDecimal aa = new BigDecimal("123");
price = aa;
}
-server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:UseTLAB -XX:+EliminateAllocations
只有 在 -verver模式下才可启用逃逸分析,参数 -XX:+DoEscapeAnalysis启用逃逸分析
方法区:类信息
和java堆一样,方法区是一块所有线程共享的内存区域。用于保存类信息,如:类的字段、方法、常量池等。
在JDK1.6、1.7中,方法区可以理解为永久区(Perm),参数:-XX:PermSize(默认64MB) -XX:MaxPermSize
动态代理会生成大量的类。
在JDK1.8中,永久区已经被彻底删除。取而代之的是元数据区,参数:-XX:MaxMetaspaceSize,这是一块堆外的直接内存。如果不指定大小,虚拟机将会耗尽系统可用的内存空间。
常用JVM参数
跟踪垃圾回收
-X:+PrintGC
-X:+PrintGCDetails
类加载/卸载的跟踪
为了更好的理解程序的执行,有时候需要知道系统加载了哪些类。
一般情况下,系统加载的类存放于文件系统中,以 jar的形式打包或以class文件的形式存在,可以直接通过文件系统查看。但是随着动态代理、AOP等技术的使用,在运行时动态生成类。
-verbose:class
跟踪类的加载和卸载-XX:+TraceClassLoading
-XX:+TraceClassUnloading
Class文件结构
class文件
在Java虚拟机规范中,Class文件使用一种类似于C语言结构体的方式进行描述,有u1,u2,u4,u8分别表示无符号单字节、2字节和8字节整数。
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count; // 常量池数量
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
class文件的标志-魔数
四个字节无符号 0xCAFFEBABE
cafe babe 0000 0034 0052 0a00 1800 2709
0028 0029 0700 2a0a 0003 0027 0800 2b0a
0003 002c 0a00 0300 2d08 002e 0a00 0300
2f0a 0030 0031 0800 320a 0033 0034 0a00
3300 3505 0000 0000 0000 03e8 0a00 0300
3608 0037 0a00 1700 3807 0039 0a00 1300
3a09 0017 003b 0a00 3000 3c07 003d 0700
3e01 0005 636f 756e 7401 0001 4901 0006
0x0000 0033 = 51 = jdk1.7
0x0000 0034 = 52 = jdk1.8