Class文件结构
- magic
    - CAFEBABE
 
- minor version
    
- major version
    
- constant_pool_count
    
- constant_pool
    - 1 CONSTANT_Utf8_info
        - 1字节
            - 标识符
 
- length
            
- bytes
            
 
- 1字节
            
- 3 CONSTANT_Integer_info
        - 4字节
            - Big-Endin(高位在前)
- int
 
 
- 4字节
            
- 4 CONSTANT_Float_info
        - 4字节
            - Big-Endin(高位在前)
- float
 
 
- 4字节
            
- 5 CONSTANT_Long_info
        - 8字节
            - Big-Endin(高位在前)
- long
 
 
- 8字节
            
- 6 CONSTANT_Double_info
        - 8字节
            - Big-Endin(高位在前)
- double
 
 
- 8字节
            
- 7 CONSTANT_Class_info
        - 2字节
            - 指向类的全限定名项的索引
 
 
- 2字节
            
- 8 CONSTANT_String_info
        - 2字节
            - 指向字符串字面量的索引
 
 
- 2字节
            
- 9 CONSTANT_Fieldref_info
        - 2字节
            - 指向申明字段的类或者接口描述符
- CONSTANT_Class_info的索引项
 
- 2字节
            - 指向字段描述符号
- CONSTANT_NameAndType_info的索引项
 
 
- 2字节
            
- 10 CONSTANT_Methodref_info
        - 2字节
            - 指向声明方法的类或者接口描述符
- CONSTANT_Class_info的索引项
 
- 2字节
            - 指向字段描述符号
- CONSTANT_NameAndType_info的索引项
 
 
- 2字节
            
- 11 CONSTANT_InterfaceMethodref_info
        - 2字节
            - 指向声明方法的类或者接口描述符
- CONSTANT_Class_info的索引项
 
- 2字节
            - 指向字段描述符号
- CONSTANT_NameAndType_info的索引项
 
 
- 2字节
            
- 12 CONSTANT_NameAndType_info
        - 2字节
            - 指向该字段或方法名称常量项的索引
 
- 2字节
            - 指向该字段或方法描述符常量项的索引
 
 
- 2字节
            
- 15 CONSTANT_MethodHandle_info
        - 1字节
            - reference_kind 1-9之间的值
- 决定了方法句柄的类型
- 方法句柄类型的值表示方法句柄的字节码行为
 
 
- 1字节
            
- 16 CONSTANT_MethodType_info
        - 2字节
            - descriptor_index
- 指向Utf8_info结构表示的方法描述符
 
 
- 2字节
            
- 18 CONSTANT_InvokeDynamic_info
        - 2字节
            - bootstrap_method_attr_index
- 当前Class文件中引导方法表的bootstrap_methods[] 数组的有效索引
 
- 2字节
            - 指向NameAndType_info表示的方法名和方法描述符
 
 
- 2字节
            
 
- 1 CONSTANT_Utf8_info
        
- access_flags
    - ACC_PUBLIC 0x0001 是否是public
- ACC_FINAL 0x0010 是否是final
- ACC_SUPER 0x0020 必须为真
- ACC_INTERFACE 0x0200 是否是接口
- ACC_ABSTRACT 0x1000 接口或抽象类
- ACC_SUNTHETIC 0x1000 编译器自动生成
- ACC_ANNOTATION 0x2000
- ACC_ENUM 0x4000
 
- this_class
    - 当前类
 
- super_class
    - 父类
 
- interface_count
    
- interfaces
- filds_count
- fields
    
- methods_count
    
- method_info
- attribute_count
- attribute
Class加载过程
- load
    
- Link:静态变量赋默认值
    - Verification
- Preparation
        
- Resolution
        - 符号引用解析为直接引用
- 常量池里面的符号解析为指针、偏移量的内存的直接引用
 
 
- Initializing
    - 调用类初始化代码
 
New对象的过程
- 申请内存
    - 赋默认值
 
- 构造方法
    - 设置初始值
 
类加载器层次
- 自顶而下:进行实际查找和加载child方向
- 
    自底向上:惊醒检查该类是否已经加载parent方向 
- 加载层级(Launcher源码)
    - Bootstrap
        - 加载lib/rt.jar charset.jar等核心类:C++实现
- sun.boot.class.path
 
- Extension
        - 加载拓展jar包,jre/lib/ext/*.jar
- 或由-Djava.ext.dirs指定
- java.ext.dirs
 
- App
        - 加载classpath指定内容
- java.class.path
 
- Custom ClassLoader
        - 自定义ClassLoader
 
 
- Bootstrap
        
- 加载机制
    - 双亲委派 -
- 为什么用双亲委派?
        - 主:安全机制
- 次:资源节约
 
 
Java并发操作
- Java并发内存模型
    - Java线程–工作内存–Save和Load操作 <===> 主内存
- Java线程–工作内存–Save和Load操作 <===> 主内存
 
- volatile
    - 字节码层面
        - ACC_VOLATILE
 
- JVM层面: volatile内存区的读写都加屏障
        - 写
            - StoreStoreBarrier
- 写操作
- StoreLoadBarrier
 
- 读
            - LoadLoadBarrier
- 读操作
- LoadStoreBarrier
 
 
- 写
            
- OS和硬件层面
        - hsdis-HotSpot Dis Assembler
            - windows lock指令实现
 
 
- hsdis-HotSpot Dis Assembler
            
 
- 字节码层面
        
- synchronized
    - 字节码层面
        - ACC_SYNCHRONIZED
- monitorenter
- monitorexit
 
- JVM层面
        - C/C++调用了系统提供的同步机制
 
- OS和硬件层面
        - X86: lock comxchg xxx
 
 
- 字节码层面
        
JVM重排序规则
- hanppens-before原则
    - JLS17.4.5
 
- as if serial
    
对象的内存布局
- 对象的创建过程?
    - class loading
- class linking()
- class initializing
- 申请对象内存
- 成员变量赋默认值
- 调用构造方法- 成员变量顺序赋初始值
- 执行构造方法语句
 
 
- 对象在内存中的存储布局?
    - 虚拟机配置
- 普通对象
        - 对象头 markword 8
- ClassPointer指针
- 实例数据
            - 引用类型:-XX:+UseCompressedOops为4字节,不开启8字节
                - ordinary object pointers
 
 
- 引用类型:-XX:+UseCompressedOops为4字节,不开启8字节
                
- Padding对齐,8的倍数
 
- 数组对象
        - 对象头 markword 8
- ClassPointer指针
            - -XX:+UseCompressedOops为4字节,不开启8字节
 
- 数组长度:4字节
- 数组数据
- 对齐,8的倍数
 
 
- 对象头具体包括什么?
    - 通过JavaAgent机制获取
        - Instrumentation
            - getObjectSize
 
 
- Instrumentation
            
- markword
        - 无锁态
- 轻量级锁
- 重量级锁
- GC标记
- 偏向锁
 
 
- 通过JavaAgent机制获取
        
- 对象怎么定位?
    - 参考
- 句柄池
        - 间接指针: GC占优
            - Object
- Class
 
 
- 间接指针: GC占优
            
- 直接指针: 执行占优
        - Object
 
 
- 对象怎么分配?
    - GC相关内容
 
- 对象大小的实例
    - new Object()对象占多少个字节?
        - 16字节
            - 对象头头8字节
- ClassPointer指针 4字节
 
 
- 16字节
            
 
- new Object()对象占多少个字节?
        
Hotspot开启内存压缩的规则
- 4G以下,直接砍掉
- 4G-32G,默认开启内存压缩 ClassPointers Oops
- 32G,压缩无效,使用64位
JVM Runtime Data Area and JVM Instructions
- Data Area
    - Program Counter
        - 存放执行位置
- 虚拟机的运行类似while循环
 
- JVM stacks
        - Frame:栈桢
            - Local Variable Table
- Operated Stacks
- Dynamic Linking
- Return Address
 
- 一个方法对应一个栈帧
            
 
- Frame:栈桢
            
- Heap
        
- Native Method stacks
        - C/C++
- JNI
 
- Direct Memory
        - NIO,zero copy
- JVM可以直接访问的内核的内存
 
- Method Area
        - run-time constant pool
- Content
            - Perm Space(< 1.8)
                - 字符串常量位于此
- FGC不会清理
- 大小启动的时候指定,不能变
 
- Meta Space(>=1.8)
                - 字符串常量位于堆区
- 会触发FGC清理
- 不设定的话,最大就是物理内存
 
 
- Perm Space(< 1.8)
                
 
 
- Program Counter
        
JVM Instruction Set
- store
- load
- pop
- mul
- sub
- add
- invoke
    - invokestatic
- invokevirtual
        
- invokeinterface
- invokespecial
        - 可以直接定位,不需要多台的方法
            - private 方法
- 构造方法
 
 
- 可以直接定位,不需要多台的方法
            
- invokedynamic:最难
        - lambda表达式
- 反射
- 其他动态语言:scala kotlin
- CGLib ASM
- 动态产生的Class
 
 
Garbage Collector GC turninig
- 熟悉GC常用算法,熟悉常见垃圾收集器,具有实际JVM调优经验
- Garbage
    - 没有引用指向的对象
- root searching
        - GC roots
            - 线程栈变量
- 静态变量
- 常量池
- JNI指针
 
 
- GC roots
            
- GC Algorithms
        - Mark-Sweep
            - 两次
 
- Copying
            - 一次
 
- Mark-Compact
            - 两次
 
 
- Mark-Sweep
            
 
- 堆内存逻辑分区(不适合不分代垃圾收集器)
    - ⚠️
        - 除了Epsilon ZGC Shenandoah 之外的GC都是使用逻辑分代模型
- G1是逻辑分代,物理不分代
- 除此之外不仅逻辑分代,而且物理分代
 
- 新生代: MinorGC/YGC
        - eden: 8
- survivor: 1
- survivor: 1
            - Copying
 
- 复制年龄超过限制时,进入old区。通过参数:-XX:MaxTenuringThreshold配置
 
- 老年代: MajorGC/FullGC
        
 
- ⚠️
        
- 内存详解
    - 栈上分配
        - 线程私有小对象
- 无逃逸
- 支持标量替换
- 无需调整
 
- 线程本地分配TLAB
        - 占用eden,默认1%
- 多线程的时候不用竞争eden就可以申请空间,提高效率
- 小对象
- 无需调整
 
- 老年代
        - 超过XX:MaxTenuringThreshold指定次数YGC
            - Parallel Scavenge 15
- CMS 6
- G1 15
 
- 动态年龄
            - s1->s2超过累加50%
- 把年龄最大的放入Old
 
- YGC期间 survivor区空间不够了,空间担保直接进入老年代
 
- 超过XX:MaxTenuringThreshold指定次数YGC
            
 
- 栈上分配
        
- 常见的垃圾回收器
    - 单线程
        - Serial
            - 安全点线程停止,
- 单CPU效率最高
- 虚拟机时Client模式的默认垃圾回收器
- 使用极少
 
- Serial Old
            
 
- Serial
            
- 多线程
        - Parallel Scavenge(PS) + Parallel Old(PO)
            - 吞吐量优先
 
- ParNew+CMS
            - CMS:
                - 开启了并发回收的过程
- CMS问题比较多
                    - 内存碎片
- 浮动垃圾
 
 
- 响应事件优先
                
 
- CMS:
                
 
- Parallel Scavenge(PS) + Parallel Old(PO)
            
- ZGC
- G1
 
- 单线程
        
- Remark阶段的算法
    - 三色扫描算法
        - 白 灰 黑
 
- 并发标记时
 
- 三色扫描算法
        
JVM调优
- -XX:+UseSerialGC
    - Serial New + Serial Old
- 小型程序
- 默认情况下不会是这种选项,Hotspot会根据计算及配置和JDK版本自动选择收集器
 
- -XX:+UseParNewGC
    - ParNew + SerialOld
- 很少用
 
- -XX:UserConcMarkSweepGC
    - ParNew + CMS + Serial Old
 
- -XX:UseParallelGC
    - Parallel Scavenge + Parallel Old
 
- -XX:UseParallelOldGC
    - Parallel Scavenge + Parallel Old
 
- -XX:UseG1GC
    - G1
 
- Linux中默认
- Linux 1.8
    - 1.8.0_181 默认 Copy MarkCompact
- 1.8.0_222 默认 PS + PO