JVM大纲

内存区域

线程私有

  1. 程序计数器 当前线程执行字节码的行号指示器
  2. 虚拟机栈 方法执行的内存模型 ,有局部变量表、操作数栈、动态链接、出口信息。
  3. 本地方法栈 执行native方法使用(原生方法、c或者c++实现)

线程共有

  1. 元空间(使用直接内存) 直接内存 运行时常量池 字符串常量池 存放的是 字面量和符号引用。
  2. 直接内存

虚拟机对象

对象创建

  1. 类加载检查
  2. 分配内存 方式 ”指针碰撞“和”空闲列表” 内存分配保证线程安全 TLAB(为每个线程预分配) CAS+重试
  3. 初始化零值
  4. 设置对象头
  5. 执行init方法

对象访问定位

  1. 使用句柄 需要有句柄池
  2. 直接指针

其他部分

  1. 字符串常量池 ”“和intern()方法 “”+””也可以
  2. new String()

垃圾回收

GC root

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象
  2. 本地方法栈(Native 方法)中引用的对象
  3. 方法区中类静态属性引用的对象
  4. 方法区中常量引用的对象
  5. 所有被同步锁持有的对象

引用类型

  1. 强引用(Strong Reference)
  2. 软引用(Soft Reference)内存不足时,会回收,用于内存敏感的高速缓存
  3. 弱引用(Weak Reference)只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,只要发现只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存
  4. 虚引用(PhantomReference) 如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。主要用于跟踪对象被垃圾回收的活动。

不可达对象是否“非死不可”

  1. 对象经过可达性分析后,发现没有被GC ROOT关联,则会被第一次标记
  2. 判断对象是否覆盖了finalize方法,没有覆盖该方法,或者说finalize方法已经执行过了,则对象就只能等死。

无用的常量

  1. 字符串常量池中有字符串未被引用,可被回

无用的类

  1. 类的所有实例被回收
  2. ClassLoader被回收
  3. 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

垃圾回收算法

  1. 标记-清除
  2. 复制
  3. 标记-整理
  4. 分代收集

垃圾收集器

  1. Serial(串行) 新生代采用标记-复制算法,老年代采用标记-整理算法。
  2. ParNew 收集器 多线程版本 CMS只能和它配合
  3. Parallel Scavenge JDK8默认使用 注重吞吐量 主要用于后台计算
  4. Serial Old
  5. Parallel Old
  6. CMS

CMS介绍

  1. 初始标记 STW 标记GC ROOT直连对象 非常快
  2. 并发标记 标记所有可达对象
  3. 重新标记 STW 时间比初始标记多一点
  4. 并发清除
    缺点: CPU资源敏感、无法处理浮动垃圾、有大量碎片(标记-清除)

G1介绍 todo

类加载

类加载过程

  1. 加载 从zip包或者其他地方加载到内存,数组由jvm直接创建
  2. 验证 文件格式、元数据、字节码等验证
  3. 准备 对类变量分配内存,并附0值。final 为初始值
  4. 解析 将常量池中的符号引用替换为符号引用
  5. 初始化 主动使用才会 初始化类
  6. 使用

类加载器分类

  1. BootstrapClassLoader 顶层类加载器
  2. ExtensionClassLoader 扩展类加载器
  3. AppClassLoader(应用程序类加载器)
    自定义类加载器,不想打破类加载器 重写 findClass。否则 重写 loadClass;

你可能感兴趣的:(JVM大纲)