整体流程
class生命周期
装载:
- 全盘负责:当前类及其所依赖、引用的类一并加载
- 父类委托:双亲委派。loadClass()–findClass()–loadClassData()–defineClass(),自定义的话就覆写findClass()
- 缓存机制:优先从缓存取,缓存没有再加载解析
验证:
文件格式验证
语法验证
准备:
static静态变量初始化零值
final常量初始化赋值
解析:
符号引用转换为直接引用
符号引用包括:类、接口的全限定名,字段名称及描述符,方法名称及描述符
初始化:
- 时机
主动按需加载 - 顺序
先父类后子类,先静态后实例
对象内存结构:
- 对象头
mark world:哈希码、分代年龄、锁状态标记
class pointer:class指针
length:数组长度 - 实例数据:不同数据类型长度不同
- 对齐填充:保证为8字节整数倍
垃圾回收
引用类型:
- 强引用
gc时,不回收 - 软引用(SoftReference)
内存不足、超时情况下会回收 - 弱引用(WeakReference)
gc时,直接回收 - 虚引用(PhantomRenference)
垃圾判断
- 引用计数
循环引用问题 - 可达性分析
GC ROOT:栈帧中局部变量表、方法区中静态变量及常量、本地方法栈中JNI元素 - finalize()
如果对象覆写了此方法,且未执行过,则对象有必要加入F-Queue,JVM将异步执行对象的finalize方法
如果执行finalize方法过程中,该对象再次被强引用,则该对象不会被回收 - 回收方法区
废弃常量
无用的类(类实例已被回收、类加载器已被回收、无引用指向类Class对象)
回收算法
- 标记清除
标记
效率低,空间碎片 - 标记整理
效率低,没有碎片
整理顺序:任意顺序(双指针)、线性顺序、滑动顺序(lisp、lisp2) - 标记复制
效率高,没有碎片,浪费一半空间
收集器
JVM参数
JMM
- Java Memory Model:java内存模型,是JVM规范,规定了一个线程如何及何时可以看到另一个线程修改后的共享变量的值,以及如何同步访问共享变量。它屏蔽了不同硬件和操作系统的内存访问差异,实现了Java程序在各种平台下一致的并发效果。
- 8种操作(read、load、use、assign、store、write、lock、unlock)
8种操作满足规则:
1.read与load是连续的,store与write是连续的
2.assign操作后必须同步到主存,没有assign操作不允许同步到主存
3.use前必须load,store前必须assign
4.一个变量在同一时刻只允许一个线程对其进行lock操作,可以lock多次
5.如果对一个变量执行lock操作,将会清空工作内存中此变量的值
6.如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作;也不允许去unlock一个被其他线程锁定的变量
7.对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作)
调试工具
- jps 查看java进程列表
- jinfo 查看正在运行的 java 应用程序的扩展参数
- jstat 对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控
- jstack 堆栈跟踪工具,用于生成java虚拟机当前时刻的线程快照,线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。
- top
- jmap 可以生成dump文件, 可以查看堆内对象示例的统计信息、查看ClassLoader的信息以及finalizer队列
执行引擎
JIT
- 热点探测
计数器探测,方法调用次数、循环回边次数 - 五个级别
- 方法内联
- 逃逸分析