JVM-垃圾回收-基础知识

基础知识

什么是垃圾

简单说就是没有被任何引用指向的对象就是垃圾。后面会有详细说明。

和C++的区别

java:GC处理垃圾,开发效率高,执行效率低

C++:手工处理垃圾,如果忘记回收,会导致内存泄漏问题。如果回收多次,则会导致非法访问问题。开发效率低,执行效率高

如何定位垃圾

引用计数法

英文:reference count,当有引用指向对象时,给引用的数量计数,当引用数量等于0时,对象就被判定为垃圾。

这种方法无法解决的问题:循环引用。例如:A > B > C > A,彼此互相引用,引用计数都是1,但其实没有任何其他引用指向他们。使用引用计数法,这些对象将永远无法垃圾回收。所以需要其他算法。Python用的是这种算法。

根可达算法

英文:Root Searching,这是JVM实际使用的算法。首先定义好一系列的根对象(GC Root),如果一个对象向上追溯没有被GC Root引用就是垃圾。那么GC Root有哪些?

线程栈变量

从main方法开始,会启动一个主线程,然后会有一个main的栈帧,这里面中的对象就是线程栈变量。

静态变量

静态变量一个类只有一个,当类初始化时,马上就会引用到静态变量,所以静态变量也是Root对象。被静态变量引用的对象不能被回收。

常量池

Runtime constant pool,常量池中引用指向的对象,类似静态变量。

JNI指针

本地方法(native)用到的类或者对象。

垃圾回收算法

标记清除(mark sweep)

第一遍:扫描整个堆,标记出可回收的垃圾。

第二遍:扫描整个堆,将刚刚标记出来的垃圾清除。

缺点:

对象清除以后内存不连续会产生空间碎片

标记和清除比较耗时,效率比较低。
在这里插入图片描述

拷贝算法 (copying)

也叫复制算法,将内存划分为两块相等的区域,每次只使用其中一块,当其中一块内存使用完了,就将还存活的对象复制到另外一块上面,然后把已经使用过的内存空间一次清除掉。

缺点:空间浪费,复制操作会增加额外开销。

优点:空间连续,没有碎片

适用场景:少量对象存活的场景

在这里插入图片描述

标记压缩(mark compact)

复制算法在 GC 之后存活对象较少的情况下效率比较高,但如果存活对象比较多时,会执行较多的复制操作,效率就会下降。而老年代的对象在 GC 之后的存活率就比较高,所以就有人提出了“标记-整理算法”。

标记过程与"标记-清除"算法类似,但是后续步骤不是直接对可回收对象进行清理,而是将所有存活的对象都向一端移动,然后清理掉端边界以外的内存。

没有碎片,效率偏低(两遍扫描,指针需要调整)
在这里插入图片描述

内存分代模型

内存分代模型也有另一个名字:分代收集算法。这种算法整合了以上所有算法的优点,最大程度避免了它们的缺点。

与其说它是算法,倒不是说它是一种策略,因为它是把上述几种算法整合在了一起。

内存分代模型是部分垃圾回收器使用的模型,也有新的垃圾回收器是不分代的。例如:Epsilon,ZGC,Shenandoah。G1 是逻辑分代,物理不分代。

根据实际场景,其实大部分的对象都很短命,一般来说,98% 的对象都是朝生夕死的,所以分代收集算法根据对象存活周期的不同将堆分成新生代和老年代。

如下图:新生代和老年代的默认比例为 1 : 2,新生代又分为 Eden 区, from Survivor 区(简称 S0 ),to Survivor 区(简称 S1 ),三者的比例为 8: 1 : 1。

在这里插入图片描述

一个对象从出生到死亡的过程

在这里插入图片描述

对象分配过程
在这里插入图片描述1. 刚刚诞生的新对象首先会尝试在栈上分配。什么样的对象会分配到栈上?

  1. 线程私有小对象。

  2. 无逃逸。(就在某1个方法中使用的对象,没有其他地方引用)

  3. 支持标量替换(例如:某些对象就2个int属性,那就可以用2个int来代替整个对象)

  4. (一般无需调整)

  5. 如果在栈上分配不下且这个对象又很大,则会直接进入老年代。

    1. 多大算大,是由一个参数控制的。
  6. 如果栈分配不下且对象不够大,默认优先放到eden区的TLAB(Thread Local Allocation Buffer)

    1. 每个线程独有区域,默认占用eden的1%
    2. 避免多线程的时候eden空间的竞争,提高效率
    3. 小对象(证明TLAB的案例)
    4. 通过-XX:-UseTLAB可以关闭(一般无需调整)
  7. eden区的对象经过一次垃圾回收之后,能回收的直接回收了。不能回收的,会移动到S1区。

  8. 再回收1次就会连同eden区的某些存活对象一起进入S2区。再回收又会进入S1区,以此往复。每次回收都会让年龄+1。

  9. 当对象的年领大于设置的值时,对象就会进入到老年代。具体要符合下面条件的任意一个。

    1. 年龄大于XX:MaxTenuringThreshold中配置的值。不同的垃圾回收器,默认值不同。
      1. Parallel Scavenge:15
      2. CMS:6
      3. G1:15
      4. 由于JVM对象结构中GC年龄是4位,所以年龄最大就是15。
    2. 动态年龄
      1. 当S1把符合条件的对象拷贝到S2时(反过来也一样)
      2. 如果此时S2的空间占用超过50%,就会把年龄最大的对象放入老年代
    3. 分配担保
      1. YGC期间 survivor区空间不够了 空间担保直接进入老年代
      2. 参考:https://cloud.tencent.com/developer/article/1082730
  10. 老年代

    1. 顽固分子
    2. 老年代满了FGC Full GC

证明TLAB的案例

下面的代码,大家可以使用idea和jvm的默认参数执行一下,然后记录一下平均执行时间。

然后加上这些jvm参数后在执行一下:-XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:-UseTLAB,应该会发现执行时间翻了接近一倍。

这些参数的含义。-XX:-DoEscapeAnalysis 关闭逃逸分析,-XX:-EliminateAllocations关闭标量替换,-XX:-UseTLAB关闭TLAB。关闭这些功能后会导致所有的对象都直接在eden区创建而不是栈中或者tlab,从而导致程序性能下降。

public class TestTLAB {class User {int id;String name;public User(int id, String name) {this.id = id;this.name = name;}}void alloc(int i) {new User(i, "name " + i);}public static void main(String[] args) {TestTLAB t = new TestTLAB();long start = System.currentTimeMillis();for (int i = 0; i < 1000_0000; i++) {t.alloc(i);}long end = System.currentTimeMillis();System.out.println(end - start);}
}

GC特点

当新生代空间不足时发生的 GC 称为 Young GC(YGC,也叫 Minor GC )

当老年代空间不足时发生的 GC 称为 MajorGC(也称为 Full GC )。此时新生代和老年代同时GC。

Minor GC 非常频繁,一般回收速度也比较快;出现了 Full GC,经常会伴随至少一次的 Minor GC,Full GC 的速度一般会比 Minor GC 慢10倍以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/1976.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【小沐学数据库】MongoDB下载、安装和入门(Python)

文章目录 1、简介2、下载和安装2.1 平台支持2.2 MongoDB Community Server2.3 MongoDB Shell2.4 MongoDB Compass2.5 pymongo库 3、概念3.1 数据库3.2 文档(Document)3.3 集合&#xff08;Collection&#xff09;3.4 元数据3.5 数据类型 4、Python代码测试4.1 连接数据库4.2 指…

oracle字符集

1、查看oracle字符集 如果操作系统或者客户端的字符集设置和数据库设置不一样就会出现乱码 查询NLS_LANG即操作系统环境变量要设为 NLS_LANGUAGE_NLS_TERRITORY**.NLS_CHARACTERSET**&#xff0c;如&#xff1a; export NLS_LANG“AMERICAN_AMERICA.AL32UTF8”

Android中构建多视图 RecyclerView的正确打开方式

Android中构建多视图 RecyclerView的正确打开方式 简介 漂亮的UI能极大提高用户留存率&#xff0c;相反糟糕的UI将导致App安装率下降。 UI体验对用户留存率有特别大的影响&#xff0c;较差的体验app我可能用不了2s就要卸载掉。 你需要学习内容如下&#xff1a; 使用单个R…

【unity实战】制作一个类帝国时代、红警——RTS战略性游戏

文章目录 先来看看实现的最终效果什么是RTS游戏一、两种方法实现相机的移动旋转缩放以及拖拽功能前言准备第一种办法1. 移动1.1 代码实现&#xff0c;里面都写了详细的中文注释&#xff0c;就不过多解释了1.2 效果&#xff1a;1.3 问题&#xff1a; 2. 缩放2.1 代码 3. 限制范围…

考场作弊行为自动抓拍告警算法 yolov7

考场作弊行为自动抓拍告警系统通过yolov7python网络模型算法&#xff0c;考场作弊行为自动抓拍告警算法实时监测考场内所有考生的行为&#xff0c;对考生的行为进行自动抓拍&#xff0c;并分析判断是否存在作弊行为。YOLOv7 的发展方向与当前主流的实时目标检测器不同&#xff…

【杂谈】关于Huawei S5720巡检过程中的“CPCAR_DROP_MPU”告警

背景 本年度二季度为某客户巡检数通设备&#xff08;Huawei居多&#xff09;时&#xff0c;在某楼宇汇聚设备上display logbuffer发现存在大量告警&#xff0c;如下&#xff1a; Jun 8 2023 15:34:24 AGG-S5720-1 %%01INFO/4/SUPPRESS_LOG(l)[58]:Last message repeated 2 t…

基于深度学习FasterRCNN模型Restnet50 的生活垃圾智能分类(准确率达84%)-含python工程全源码

目录 前言总体设计系统整体结构图系统流程图 运行环境1. 硬件环境2. Python 环境 模块实现1. 数据预处理2. 数据加载3. 模型构建4. 模型训练及保存5. 模型加载与调用 系统测试1. 模型准确率2. 分类别准确率 工程源代码下载其它资料下载 前言 本项目基于Faster R-CNN模型&#…

Service 基础

今天开始来分享Service 的基础知识&#xff0c;后续我们可以慢慢打磨&#xff0c;分享 Service 的进阶知识和原理 Service 基本概念 Service 是 K8S 最核心的概念了 我们可以通过创建 Service &#xff0c;为一组具有相同功能的容器应用提供一个统一的入口地址&#xff0c;并…

【Java】Java核心 80:Git 教程(3)初始化工作区 add与commit

文章目录 04.GIT本地操作-初始化工作区目标内容小结 05.GIT本地操作-add与commit目标内容小结 在Git中&#xff0c;初始化工作区并使用add和commit命令是进行版本控制的基本操作。 下面是对这些操作的简要解释&#xff1a; 初始化工作区&#xff1a;在使用Git之前&#xff0c…

Chapter 1: Introduction - Why Program? | Python for Everybody 讲义_Cn

文章目录 Python for Everybody课程简介适合所有人的 Python (Why Program?)为什么要学习写程序&#xff1f;创造力和动力计算机硬件架构了解编程单词和句子与 Python 对话术语&#xff1a;解释器和编译器Writing a program什么是程序&#xff1f;The building blocks of prog…

隐式迭代是什么意思?jQuery选择器隐式迭代

在使用jQuery 选择器获取元素后&#xff0c;如果不考虑获取到的元素数量&#xff0c;直接对元素进行操作&#xff0c;则在操作时会发生隐式迭代。隐式迭代是指&#xff0c;当要操作的元素实际有多个时&#xff0c;jQuery 会自动对所有的元素进行操作&#xff0c;示例代码如下。…

“暗网议会”如今已成为现实

图片来源:Marcin Balcerzak 最近&#xff0c;“暗网议会”已经成为了网络犯罪分子试图证明自己影响力的最新流行语&#xff0c;安全内部人士对这个词也很感兴趣。 上周五&#xff0c;臭名昭著的亲俄黑客组织Killnet在其电报威胁帖子中使用了这个词语。随后&#xff0c;twitte…