JVM - 内存及垃圾回收

时间:2021-05-20 00:03:38

JVM - 内存及垃圾回收

1、jvm运行时数据区域

  • 方法区

    • 线程共享

    • 存储加载的Class信息、常量、静态变量,

    • 也称为永久代(perm区)

    • 内存无法扩展时,抛出OutOfMemoryError

  • 虚拟机栈

    • 线程私有

    • 每个方法被执行时都会创建,存储局部变量表、操作数栈、动态链接、方法出口等。局部变量表存放的基本数据类型及对象引用

    • 如果线程请求的栈深度大于jvm允许的深度,抛出*Error;如果虚拟机栈动态扩展时无法申请到足够的内存,抛出OutOfMemoryError

  • 本地方法栈

    • 与虚拟机栈类似,但是为Native方法服务,虚拟机栈为Java方法服务
    • 线程共享

    • 存储所有对象实例及数组

    • 细分为新生代和老年代,新生代包括Eden,From Survivor,To Survivor

    • 内存无法扩展时,抛出OutOfMemoryError

    • 默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 )

    • 新生代中,默认:Edem : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定 )

  • 程序计数器

    • 线程私有

    • 较小内存,当前线程执行的字节码的行号指示器,没有规定OOM

2、GC

2.1、 判断对象是否可用

  • 当对象到GC Roots没有任何引用链时,则对象不可达,即对象不可用

  • GC Roots的对象:

    • 虚拟机栈中的引用的对象

    • 方法去中类静态属性引用的对象

    • 方法区中常量引用的对象

    • native方法引用的对象

2.2、引用

  • 强引用

    • 最常用的引用,只要存在,对象就不会被回收
  • 软引用(Soft Reference)

    • 用来描述还有用,但并非必需的对象

    • 对于软引用的对象,系统将要发生内存溢出之前,将会把这类对象进行二次回收

  • 弱引用(Weak Reference)

    • 弱引用的对象只能存活到下一次垃圾收集发生之前,当垃圾回收时,弱引用的对象会被回收掉

2.3、垃圾收集算法

  • 复制算法

    • 用于新生代

    • 分配内存时,每次使用Eden和S0,回收时,将存活的对象拷贝到S1,最后清理掉Eden和S0

  • 标记-整理算法

    • 用于老年代

    • 先标记需要清理的内存,将存活的对象都向一端移动,然后清理掉边界意外的内存

2.4、内存分配及回收策略

  • 对象优先在Eden分配,当Eden区没有足够的空间时,会发起一次Minor Gc

  • 大对象直接进入老年代

  • 长期存活的对象将进入老年代,对象在Survivor每熬过一次Minor GC,年龄就加1,年龄达到一定值(年龄阈值默认15,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域