-
类的生命周期
加载:类加载子系统将class文件加载到内存中,加载class文件。
验证:验证的目的是确保class文件的字节流中信息符合虚拟机的要求,不会危害虚拟机安全,文件格式验证,字节码验证等。
准备:为静态变量分配内存,并设置为JVM的默认初始值,而不是我们在程序中设置的初始值。非静态变量不分配内存。
解析:将常量池中的符号引用替换为直接引用。
初始化:真正意义执行java代码,执行构造器,为静态变量赋值,执行静态代码块。
使用:使用该类提供的功能,包括主动引用与被动引用。
卸载:被GC回收。
类的加载时机(初始化):初始化部分如果类的父类没有初始化,则必须触发父类先初始化,遇见new、getstatic、putstatic、invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。反射调用时,没有进行初始化需要先初始化。
主动引用:通过new 关键字实例化类,读取或设置类的静态方法与属性。
被动引用:引用父类的静态变量,只会引起父类的初始化,不会引起子类初始化,创建当前类的数组以及常量不会引起类初始化。
主动引用会引起类的初始化,被动引用不会引起类的初始化。
============================================================================= -
类加载器
分类:启动类加载器(jre/lib),扩展类加载器(jre/lib/ext),应用类加载器。(优先级依次降低)
加载器特点:双亲委托,当遇见一个加载类的请求时,当前加载器并不会加载,而是将请求委托给父类加载,直到顶层(启动类加载器)以及父类加载器没有加载过,当前类才会尝试去加载,这样的好处是避免了类的重复加载,如果父类加载器有加载过,则直接引用,缓存加载。 -
JVM运行时数据区域
类加载子系统将class文件加载入内存,但是class文件并不能直接被cpu进行执行,需要用到特定的解析器,执行引擎进行解析,在解析的过程中会涉及到调用本地库接口。
主要包括以下部分:
程序计数器:保存当前正在执行的JVM指令地址,字节码解析器通过改变程序计数器内的值来读取下一条需要执行的字节码指令。
Java虚拟机栈:每一个线程在创建时,会创建一个Java虚拟机栈,其中存放着栈帧,栈帧包括:局部变量表,操作数栈,动态链接(class引用,指向当前方法在常量池中的对应的class),以及方法返回地址。每一个栈帧的创建到释放即一个方法的调用到结束。
本地方法栈:与Java虚拟机栈作用一样,不过本地方法栈服务虚拟机调用本地方法的。
(以上是线程私有,以下是线程共享)
堆: 所有的对象以及数组的创建都在这里,分为eden,s0,s1 区,比例8:1:1。
方法区:存放JIT编译后的代码,被虚拟机加载的类的信息,静态变量,常量池。
-
字节码相关
javac Hello.java 进行编译 java Hello进行运行字节码, javap -c -verbose Hello.class反编译字节码文件并展示细节。每个线程有自己的线程栈存放栈帧,即上面提到的虚拟机栈,这里涉及到本地变量表与操作数栈的load与store。
方法调用的指令:
invokestatic:调用某个类的静态方法,最快。
invokespecial: 用来调用构造函数,也可以调用类中private修饰的方法。
invokevirtual: 调用public 默认,protected修饰的方法。
invokeinterface: 通过接口调用方法。
invokedynamic: java7新增的,java8支持lambda的基础。 -
GC相关工具及JVM参数
-D设置系统属性:-Dfile.encoding=utf-8。
-Xms初始堆大小 -Xms8g 。
-Xmn 年轻代大小 -Xmn1g 等价于-XX: NewSize。
使用 G1 垃圾收集器 不应该 设置该选项,在其他的某些业务场景下可以设置。官方建议设置为 -Xmx 的 1/2 ~ 1/4。
-Xmx堆的最大内存 -Xmx8g。
-XX: 用于控制JVM的行为,-XX:±是对布尔值进行控制 -XX: +UseG1GC
-XX: key=value 指定某个选项的值 -XX: MaxPerSize=256m。
-Xss:每个线程栈的字节数,例如 -Xss1m 指定线程栈为 1MB与-XX:ThreadStackSize=1m 等价。
-XX:MaxPermSize=size, 这是 JDK1.7 之前使用的。Java8 默认允许的Meta空间无限大,此参数无效。-XX:MaxMetaspaceSize=size, Java8 默认不限制 Meta 空间, 一般不允许设置该选项。
-XX:+UseG1GC:使用 G1 垃圾回收器
-XX:+UseConcMarkSweepGC:使用 CMS 垃圾回收器
-XX:+UseSerialGC:使用串行垃圾回收器
-XX:+UseParallelGC:使用并行垃圾回收器
jps -lvm 查看进程的详细信息
jinfo pid 查看进程信息
jstat -gc pid 1000(1000ms表示一秒打印1次) 1000(打印1000次)
jstat -gcutil 1000 1000 (gcutil展示的是百分比)
jmap -heap pid (打印堆内存的配置信息)
jmap -histo pid (查看哪些类占用的内存最多)
jmap -dump:format=b, file=xxx.hprof (dump堆内存)
jstack -l pid 查看线程相关信息
jcmd pid help 可以进行哪些信息的查看
jcmd pid VM.version
jcmd pid VM.flags
jcmd pid VM.command_line
jcmd pid VM.system_properties
jcmd pid Thread.print
jcmd pid GC.class_histogram
jcmd pid GC.heap_info
jvm图形化工具jconsole
jvm图形化工具jvisualvm
jvm图形化工具jmc