JVM
内存模型
堆(线程共享):存放对象实例,数组。
虚拟机栈(线程私有):局部变量表,操作栈,动态连接,方法出口。
本地方法栈:虚拟机使用到的Native方法服务。
程序计数器:行号指示器,占用较小的内存空间(不会发生OutOfMemoryError),用于标记当前线程所执行的字节码位置。
元数据区(方法区/永久代):类信息,常量,静态变量。
垃圾收集器
Serial,单线程收集器,采用一个CPU或一条线程去完成垃圾回收(复制算法),暂停其他所有的工作线程。
ParNew,Serial的多线程版本,第一次实现了让垃圾收集器线程和用户线程同时工作。目前只有它能与CMS收集器配合工作。一个CUP情况下效率不如Serial收集器。
ParallelScavenge,相对ParNew而言,拥有GC自适应的调节策略,即动态调整新生代Eden,Survivor,老年代比例以提供最合适的停顿时间或最大的吞吐量。
SerialOld,单线程和“标记-整理”算法。
ParallelOld,多线程和“标记-整理”算法。
CMS,一种以获取最短回收停顿时间为目标的收集器(并发低停顿收集器)。过程:初始标记(StopTheWorld) -> 并发标记(占用用户线程) -> 重新标记(StopTheWorld) -> 并发清除(占用用户线程)。CUP敏感,无法处理浮动垃圾,产生碎片空间。添加-XX:+UseCMSCompactAtFullCollection参数可以在触发FullGC后会进行碎片整理。
G1,在有限的时间内可以获得最高的收集效率。将整个Java堆划分为多个大小固定的独立区域,并且跟踪这些区域的垃圾堆积程度在后台维护一个列表,每次根据允许的收集时间,优先回收垃圾最多的区域。
组合方式

对象是否存活
引用计数:对象之间的相互循环引用的问题无法解决。
根搜索:根对象包括虚拟机栈中引用的对象,方法区中的类静态属性引用的对象,方法区中常量引用的对象,本地方法栈中JNI(Native方法)引用的对象。
垃圾回收算法
标记清除:产生大量不连续的内存碎片,无法分配大空间。
复制:牺牲一半的内存空间。对象存活率高时效率会变低。
标记整理:对复制算法的改良,适用于老年代。
分代收集:商业基本都采用。
性能监控和故障处理
JDK命令行工具
Jps:显示指定系统内所有的虚拟机进程。
Jstat:用于收集虚拟机各方面的运行数据。
Jinfo:显示虚拟机配置信息。
Jmap:生成虚拟机的内存转储快照(headdump文件)。
Jhat:用于分析headdump文件,它会建立一个http/html服务器,让用户在浏览器上查看分析结果。
Jstack:显示虚拟机线程快照。
JDK可视化工具
JConsole:查看当前堆内存,线程,类,VM等相关信息。启动JConsole后将自动搜索出本机运行的所有虚拟机进程,允许远程功能来连接远程服务器进行监控,选中进程即可开始监控。
VisualVM:显示虚拟机进程及进程的配置和环境信息(jps,jinfo),监视应用程序的CUP、GC、堆、方法区及线程信息(jstat,jstack),dump及分析堆转储快照(jamp,jhat),方法级的程序运行性能分析,找到被调用最多,运行时长的方法。离线程序快照(收集程序的运行时配置,线程dump,内存dump等信息建立一个快照,可以将快照发送开发者处进行Bug反馈)等。
类加载机制
载入:将字节码从不同的数据源(class文件、jar包)转化为二进制字节流加载到内存中,并生成一个该类的Class对象。
验证:校验二进制字节流是否符合JVM字节码规范和语法规范。
准备:为静态变量分配内存,并初始化为默认初始值,常量会初始化为期望值。
解析:符号引用转化为直接引用(即解析com.demo.A引用,找到类A实际物理地址)。
初始化:为静态变量赋期望值(即执行类构造器方法[静态块])
类加载器
启动类加载器(Bootstrap ClassLoader),加载<JAVA_HOME>/lib/*.jar。
扩展类加载器(Extension ClassLoader),加载<JAVA_HOME>/lib/ext/*.jar。
应用类加载器(Application ClasLoader),加载用户类路径下所指定的类库。
双亲委派
一个类加载器收到了加载类的请求,会先把请求委托给上层加载器去完成,上层加载器又会委托上上层加载器,一直到最顶层的类加载器;如果上层加载器无法完成类的加载,当前类加载器才会尝试自己去加载这个类。保证同一个类最终会被特定的类加载器加载。
浙公网安备 33010602011771号