当前位置:网站首页>JVM GC垃圾回收简述

JVM GC垃圾回收简述

2022-07-07 17:52:00 whiteye太白

GC

针对java堆的回收。

可达性分析算法:从gc root搜索引用链。

Eden区满时触发minor gc,存活的对象进入survivor区(复制算法),年龄加1,当对象年龄大于阈值(默认15)时,进入老年代。可以通过参数设置阈值,虚拟机运行过程中会进行动态调整。当某个年龄大小超过survivor区一半(默认50%)时,取这个年龄和MaxTenuringThreshold中最小的作为新的阈值。

新生代(标记-复制算法)

  • 标记存活对象-因为存活对象较少
  • 内存大小eden:to:from = 8 : 1 : 1
  • minor gc后,Eden区存活的对象被复制到“survivor To”;“survivor From”区中存活的对象,年龄达到阈值就进入年老代,否则被复制到“survivor To”中。survivor From 和survivor To互换。
  • survivor From空间不够用,则放不下的部分会提前进入老年代。

老年代(标记-清除-整理算法)

老年代内存不够时进行full gc(标记-清除),多次full gc后进行整理。次数参数CMSFullGCsBeforeCompaction默认为0次。

强引用:gc不回收。
软引用:内存不足时才回收。
弱引用:gc回收。
虚引用:用于回收前,得到系统通知,可以在回收前进行一些处理。

java内存模型

  1. 程序计数器:控制程序执行。
  2. Java虚拟机栈:存储局部变量表、操作数栈、动态连接、方法出口等。
  3. 本地方法栈:存储本地(native)方法信息。
  4. Java堆:存储对象实例。
  5. 方法区:存储静态数据(常量、静态变量等)。包含运行时常量池:存储常量。

Java堆回收算法

  1. 引用计数法(多数虚拟机不用)
  2. 可达性分析算法
    根据“根对象”搜索其“引用链”判断某对象是否可达,对不可达对象进行筛选,若该对象存在finalize()方法,并且finalize()方法没被执行过,则将该对象放置于队列中,由Finalizer线程执行其finalize()方法来释放该对象。如果队列中的对象在执行finalize()释放前被重新引用,就会移出释放队列。JDK9后被移除。

回收对象判断

  1. 回收不存在引用的字符串常量(字符串常量池在堆中,运行时常量池在方法区)
  2. 不在被使用的类,仅仅是“被允许回收”
    同时满足:
    该类所有实例都被回收;
    该类的类加载器已被回收;
    该类的Class对象不存在被引用,无法进行发射访问。

GC触发条件

Minor GC触发条件:Eden区满时。

Full GC触发条件:

  1. 调用System.gc时,系统建议执行Full GC,但是不必然执行。
  2. 老年代空间不足。
  3. 方法区空间不足。
  4. 通过Minor GC后进入老年代的平均大小大于老年代的可用内存。
  5. 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。

【补充】 JDK 7 之前,HotSpot 使用永久代来实现方法区的时候,实现是完全符合这种逻辑概念的。 而在 JDK 7 及之后,HotSpot 已经把原本放在永久代的字符串常量池、静态变量等移动到堆中,这个时候类变量则会随着 Class 对象一起存放在 Java 堆中。

原网站

版权声明
本文为[whiteye太白]所创,转载请带上原文链接,感谢
https://blog.csdn.net/demo_yo/article/details/125592799

随机推荐