JVM线程

lwx_R / 2023-08-18 / 原文

1.JVM概念

包括一套字节码指令集 一组寄存器 一个栈 一个垃圾回收 一个堆 一个存储方法域。
Java源文件(通过编译器)-> 字节码文件(通过JVM)-> 机器码

1.1 子系统

  • ClassLoader类加载:根据给定的全限定类名来装载class文件到Runtime data area中的method area
  • ExecutionEngine 执行引擎:执行classes中的指令

1.2 组件

  • Runtime data area 运行时数据区:JVM内存
  • Native Interface 本地接口:与native libraries交互,是其他编程语言交互的接口

1.3 流程

编译器将Java代码转化为字节码,类加载器再把字节码加载到内存中,将其放在运行时数据区的方法区,字节码文件只是JVM的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定命令解释器引擎,将字节码翻译成底层系统指令,再交由CPU执行,需要调用其他语言的本地库接口来实现整个程序功能

2.线程

JVM允许一个应用并发执行

3.内存区域

3.1 线程私有区域 Thread Local

3.2 线程共享区域 Thread Shared

3.2.1 方法区(永久代)

用于存储被JVM加载的类信息,常量,静态变量,被编译器编译后的代码等数据。Class在被加载时候被放入永久区域,GC不会在主程序运行期间对永久代区域进行清理,最终会OOM异常。

  • Java8中,永久代被移除,被元数据区取代,其不在虚拟机中,使用本地内存。

3.2.2 类实例区(Java堆)

  • 新生代
    存放新生对象 占据1/3空间,会频繁触发MinorGC进行垃圾回收
    分为Eden,ServivorFrom,ServivorTo三个区
    -- Eden: 新对象的出生地(占用内存大直接分配老年代),内存不够触发MinorGC,对新生代进行垃圾回收。
    -- SurvivorFrom:上一次GC的幸存者,作为这次GC被扫描者
    -- SurvivorTo: 保留了一次MinorGC过程中的幸存者
    俩个Survivor意义:减少被送往老年代对象,进而减少GC发生,预筛选保证,只有经历过15次MinorGC还能在新生代存活的对象才会送往老年代。

  • 老年代
    存放生命周期长的内存对象,比较稳定。进行MajorGC前一般先进行MinorGC。无法找到足够大的连续空间分配给新建的较大对象也会触发MajorGC进行垃圾回收

  • 异常

3.3 直接内存 Dirct Memory

4.垃圾回收机制和算法


虚拟机自动执行释放对象内存
GC:Gabage Collection 垃圾收集,创建对象时,GC开始监控这个对象的地址,大小以及使用情况。GC采用有向图方式记录和管理堆中所有对象,当一些对象不可达时就回收这些空间。

4.1 确定垃圾

  • 引用计数法
  • 可达性分析
  • 标记清除算法
  • 复制算法
  • 标记整理算法
  • 分代收集算法

4.2 引用类型

  • 强引用:把一个对象赋给一个引用变量,这个引用变量就是一个强引用。其不可能被垃圾回收机制回收,会造成内存泄漏
  • 软引用:用SoftReference类实现,对于只有软引用对象,内存足够时不会回收,不足时会被回收
  • 弱引用:WeakReference类实现,只要垃圾回收机制一运行,就会被回收
  • 虚引用:PhantomReference类实现,必须和引用队列联合使用。主要作用:跟踪对象被垃圾回收的状态

4.3 GC分代收集算法

  • 新生代:复制算法
  • 老年代:标记清除、整理算法

4.4 分区收集算法

将堆空间划分为连续的不同小区间,每个小区间独立使用,独立回收,控制一次回收多少个小区间。

4.5 GC分类

  • FullGC 清理整个堆空间,速度非常慢,当永久代满了触发
  • Minor GC:发生在新生代,eden区满触发,新对象大小超过eden区所剩空间
  • Major GC:老年代,晋升到老年代对象大于剩余空间,MinorGC后存活对象超过老年代剩余空间,System.gc()执行,CMS GC异常,堆内存分配很大对象

5.垃圾回收器