jvm学习笔记(二) ----- 垃圾回收

news2024/11/17 13:35:06

GC

  • 一、判定对象是否是垃圾
    • 1.引用计数法
    • 2.可达性分析算法
  • 二、垃圾回收算法
    • 1.标记清除
    • 2.标记整理
    • 3. 复制
    • 4. 分代垃圾回收
      • 1.尝试在伊甸园分配
      • 2.大对象直接晋升至老年代
      • 3.多次存活的对象
      • 4.老年代连续空间不足,触发 Full GC

链接: jvm学习笔记(一) ----- JAVA 内存
链接: jvm学习笔记(三) ----- 垃圾回收器

一、判定对象是否是垃圾

1.引用计数法

  • 有一个地方引用对象,计数加一,当计数为零表示可以回收
  • 缺点是难以解决对象之间的循环引用问题

2.可达性分析算法

  • java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象。它从一系列 GC Roots 出发,边标记边探索所有被引用的对象
  • 从 GC Root对象 为起点,看是否能沿着引用链找到该对象,找不到,表示可以回收
  • GC Root对象 包括栈帧中的局部变量、方法区中的静态变量、方法区中的常量、本地方法栈中JNI引用的对象
  • 为了防止在标记过程中堆栈的状态发生改变,Java 虚拟机采取安全点机制来实现 Stop-the-world (应用程序的线程全部停止) 操作,暂停其他非垃圾回收线程
  • 当然,安全点的初始目的并不是让其他线程停下,而是找到一个稳定的执行状态。在这个执行状态下,Java 虚拟机的堆栈不会发生变化。这么一来,垃圾回收器便能够“安全”地执行可达性分析

二、垃圾回收算法

1.标记清除

第一遍标记、第二遍收集。缺点是会产生内存碎片,碎片过多,仍会使得连续空间少
在这里插入图片描述

2.标记整理

第一遍标记、第二遍整理,整理是指存活对象向一端移动来减少内存碎片,相对效率较低
在这里插入图片描述

3. 复制

开辟两份大小相等空间,一份空间始终空着,垃圾回收时,将存活对象拷贝进入空闲空间,优点是不会有内存碎片,但占用空间多。
在这里插入图片描述

4. 分代垃圾回收

  1. 大部分的 Java 对象只存活一小段时间,而存活下来的小部分 Java 对象则会存活很长一段时间。
  2. 根据对象的特点分代(分区域)来进行,分为新生代和老年代,新生代对象一般很少存活,采用『复制算法』、老年代对象生存时间长,适合采用『标记-清除算法』或『标记-整理算法』
  3. 堆内存分为『新生代』和『老年代』,『新生代』又分为『伊甸园』和两个『幸存区』。新生代内存不足触发的 GC 称为 Minor GC ,暂停时间很短,老年代内存不足触发的 GC 称为 Full GC 暂停时间较长,一般是新生代 GC 的几十倍,它们使用的垃圾回收算法不同,见之前的介绍。

1.尝试在伊甸园分配

对象优先在『伊甸园』分配,当『伊甸园』没有足够的空间时,触发 Minor GC ,将『伊甸园』和『幸存区 From』中仍然存活的对象利用 复制算法 移入『幸存区 To』,然后交换『幸存区 From』和『幸存区 To』的位置。

默认情况下,Java 虚拟机采取的是一种动态分配的策略(对应 Java 虚拟机参数 -XX:+UsePSAdaptiveSurvivorSizePolicy),根据生成对象的速率,以及 Survivor区的使用情况动态调整 Eden 区和 Survivor 区的比例。当然,你也可以通过参数 -XX:SurvivorRatio 来固定这个比例。但是需要注意的是,其中一个 Survivor 区会一直为空,因此比例越低浪费的堆空间将越高。

情况1:伊甸园空间还够,新对象在伊甸园能够存储的下,这时候不会发生GC。图中白色区域是空闲空间、蓝色矩形表示已创建对象。
在这里插入图片描述
情况2:伊甸园空间不够了。

在这里插入图片描述
标记可回收的对象,图中用黄色表示,这时候会用户线程会被暂停(Stop The World)。

在这里插入图片描述
触发新生代的垃圾回收,称为 Minor GC ,幸存对象移入『幸存区 To』,注意这里用的是复制算法,因此在幸存区没有碎片。
在这里插入图片描述
最后的结果,注意 GC 完成后,From 和 To 交换了位置,另外幸存区的对象开始记录寿命。
在这里插入图片描述

2.大对象直接晋升至老年代

当对象太大,伊甸园包括幸存区都存放不下时,这时候老年代的连续空间足够,此对象会直接晋升至老年代,不会发生 GC

在这里插入图片描述
结果:
在这里插入图片描述
测试:

  1. 预先定义一组大小
    private static final int _512KB = 512 * 1024;
    private static final int _1MB = 1024 * 1024;
    private static final int _6MB = 6 * 1024 * 1024;
    private static final int _7MB = 7 * 1024 * 1024;
    private static final int _8MB = 8 * 1024 * 1024;

在运行时添加如下 JVM 参数:

-XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8

参数含义 :

-XX:+UseSerialGC 是指使用 Serial + SerialOld 回收器组合
-XX:+PrintGCDetails -verbose:gc 是指打印 GC 详细信息
-Xms20M -Xmx20M -Xmn10M 是指分配给 JVM 的最小,最大以及新生代内存
-XX:SurvivorRatio=8 是指『伊甸园』与『幸存区 From』和『幸存区 To』比例为 8:1:1

  1. 最开始,没什么对象:
public static void main(String[] args) {
		
}

测试结果:
在这里插入图片描述

  1. 当代码改为
    public static void main(String[] args) {
        byte[] obj1 = new byte[_7MB];
    }

可以预料到,因为「eden space 8192K, 30% used」已经放不下 7MB 的对象,必然会触发新生代的 GC:
在这里插入图片描述

  1. 可以看到,结果是一部分旧的对象进入了幸存区「from space 1024K, 73% used」,而伊甸园里放入了 7MB 的对象「eden space 8192K, 88% used」再放入一个 512KB 的对象
public static void main(String[] args) {
    byte[] obj1 = new byte[_7MB];
    byte[] obj2 = new byte[_512KB];
}

在这里插入图片描述
可以看到,伊甸园几乎被放满了「eden space 8192K, 98% used」,但毕竟没有满,所以没有触发第二次 GC继续放入一个 512KB 的对象.

  1. 果然触发了第二次 GC,其中一个 512KB 的对象进入了幸存区「from space 1024K, 52% used」而那个 7MB 的对象晋升至了老年代「tenured generation total 10240K, used 7848K」
public static void main(String[] args) {
    byte[] obj1 = new byte[_7MB];
    byte[] obj2 = new byte[_512KB];
    byte[] obj3 = new byte[_512KB];
}

在这里插入图片描述

3.多次存活的对象

在幸存区历经多次 GC 还存活的对象会晋升至老年代,默认晋升的阈值是 15,也就是说只要经历 15 次回收不死,肯定晋升,但注意如果目标 survivor 空间紧张,也不必等足 15 次,可以提前晋升

-XX:MaxTenuringThreshold=threshold

Sets the maximum tenuring threshold for use in adaptive GC sizing. The largest value is 15. The default value is 15 for the parallel (throughput) collector, and 6 for the CMS collector.

-XX:TargetSurvivorRatio=percent

Sets the desired percentage of survivor space (0 to 100) used after young garbage collection. By default, this option is set to 50%.

4.老年代连续空间不足,触发 Full GC

public static void main(String[] args) {
    byte[] obj1 = new byte[_8MB];
    byte[] obj2 = new byte[_8MB];
}

第一个 8MB 直接进入老年代,第二个 8MB 对象在分配时发现老年代空间不足,只好尝试先进行一次 Minor GC ,结果发现新生代没有连续空间,只好触发一次 Full GC ,最后发现老年代也没有连续空间,这时出现 OutOfMemoryError

果把代码改为下面的样子,则只会触发 Minor GC ,之后,老年代能够容纳 obj2,所以不会触发 Full GC

public static void main(String[] args) {
    byte[] obj1 = new byte[_8MB];
    obj1 = null;;
    byte[] obj2 = new byte[_8MB];
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

20240607每日通信--------VUE3前端引入scoket-io,后端引入Netty-SocketIO,我成功了,希望一起交流沟通

无语 前置: VUE3 前端集成scoket-io socket.io-client Sringboot 3.0JDK17集成Netty-SocketIO Netty-SocketIO 失败原因一: 前期决定要写demo时候,单独了解了,后端引入Netty-SocketIO注意事项,详见我先头写的博客 前…

别让你的品牌失去声音,品牌策划如何成为你的王牌?

品牌策划可不仅仅是一个简单的概念,它是一门真正的艺术和科学。 它涉及到在确立品牌定位之后,进行一系列精心设计的传播和推广活动,从而塑造和管理品牌,让品牌价值达到最大化。 在这个竞争激烈的市场中,想要让你的品…

一篇文章带你搞懂C++引用(建议收藏)

引用 6.1 引用概念 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。 比如:李逵,在家称为"铁牛",江湖上人称&quo…

30、matlab现代滤波:维纳滤波/LMS算法滤波/小波变换滤波

1、信号1和信号2的维纳滤波 实现代码 N 2000; %采样点数 Fs 2000; %采样频率 t 0:1 / Fs:1 - 1 / Fs; %时间序列 Signal1 sin(2*pi*20* t) sin(2*pi*40* t) sin(2*pi*60* t); Signal2[2*ones(1,50),zeros(1,50),-1*ones(1,100),zeros(1,50),-2*ones(1,50),zeros(1,50),1…

删除目录

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 删除目录可以通过使用os模块提供的rmdir()函数实现。通过rmdir()函数删除目录时,只有当要删除的目录为空时才起作用。rmdir()函数的基本语…

升级最新版openssh-9.7p1及openssl-1.1.1h详细步骤及常见问题总结

近期因为openssh相继被漏洞扫描工具扫出存在漏洞,所以考虑升级操作系统中的openssh和openssl为最新版本,来避免漏洞风险。期间的升级过程及遇到的疑难问题,特此记录下来,供有需要的人参考。 本次目标是升级 openssh 为 9.7p1 版本…

算法金 | 不愧是腾讯,问基础巨细节 。。。

大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 最近,有读者参加了腾讯算法岗位的面试,面试着重考察了基础知识,并且提问非常详细。 特别是关于Ada…

Linux守护进程揭秘-无声无息运行在后台

在Linux系统中,有一些特殊的进程悄无声息地运行在后台,如同坚实的基石支撑着整个系统的运转。它们就是众所周知的守护进程(Daemon)。本文将为你揭开守护进程的神秘面纱,探讨它们的本质特征、创建过程,以及如何重定向它们的输入输出…

vue2实现将el-table表格数据导出为长图片

方法一、 el-table数据导出为长图片 将el-table数据导出为图片不是一个直接的功能,但可以通过以下步骤实现: 使用html2canvas库将表格区域转换为画布(canvas)。 使用canvas的toDataURL方法将画布导出为图片格式(例如PNG)。 创建…

人工智能时代,想转型AI产品经理?这篇文章你不应该错过

前言 在这个日新月异的智能时代,人工智能(AI)已经从未来概念转变为推动各行各业发展的核心驱动力。作为连接技术与市场的桥梁,AI产品经理的角色愈发关键,他们不仅是技术的翻译者,更是创新的推动者。如果你…

ORA-12519 TNS:no appropriate service handler found

问题描述 jdbc连接Oracle失败,报错日志如下: Listener refused the connection with the following error: ORA-12519, TNS:no appropriate service handler found The Connection descriptor used by the client was:192.9.100.217:7001:wcm 问题分…

重新学习STM32(2)NVIC

概念简介 NVIC,即嵌套向量中断控制器,控制着中断相关的功能,是内核里面的一个外设。 中断在单片机编程中的作用是使单片机能及时响应需要立即处理的事件,但是这些事件也分紧急和非紧急,因此需要优先级来区分。…

泛微开发修炼之旅--10基于Ecology实现附件上传,并将上传后的文件id存入表单附件控件中的示例及源码

文章链接:泛微开发修炼之旅--10基于Ecology实现附件上传,并将上传后的文件id存入表单附件控件中的示例及源码

Cadence Virtuoso IC617 系统内存清理

1、清空simelation和垃圾箱下的文件 2、在虚拟机磁盘路径下,例如/home下面输入后,回车,等待进程走完,虚拟机关机。 cat /dev/zero > zero.fill;sync;sleep 1;sync;rm -f zero.fill 3、在windows下winR ->cmd 找到VMware安…

代码随想录算法训练营第十五天| 110.平衡二叉树、 257. 二叉树的所有路径、404.左叶子之和

110.平衡二叉树 题目链接:110.平衡二叉树 文档讲讲:代码随想录 状态:还可以 思路:计算左右子树的深度差,递归判断左右子树是否符合平衡条件 题解: public boolean isBalanced(TreeNode root) {if (root n…

【UML用户指南】-10-对高级结构建模-高级类

目录 1、类目 2、高级类 3、可见性 4、实例范围和静态范围 5、抽象元素、叶子元素和多态性元素 6、多重性 7、属性 8、操作 9、模板类 10、标准元素 1、类目 类目 (classifier)是描述结构特征和行为特征的机制。类目包括类、关联、接口、数据类…

6月26~28日,2024北京国际消防展即将开幕!

随着社会的快速发展,消防安全日益受到广大民众的高度关注。为了进一步推动消防科技的创新与发展,提升全民消防安全意识,2024年北京消防展将于6月26日在北京国家会议中心盛大开展。目前:观众预登记已全面启动,广大市民和业界人士可…

第九篇——冗余量:《史记》和《圣经》那个信息量大?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 通过信息量的对比,引出来冗余度的概念,又深入浅出…

[职场] 项目实施工程师的工作前景 #笔记#经验分享

项目实施工程师的工作前景 项目实施工程师是负责将软件产品或解决方案实施到客户现场并确保项目成功落地的工作岗位。他们要负责整个项目的规划、组织、执行和控制,确保项目按照预定的进度、质量和预算完成。 一.工作内容 1. 项目规划:确定…

计算机网络 期末复习(谢希仁版本)第3章

对于点对点的链路,目前使用得最广泛的数据链路层协议是点对点协议 PPP (Point-to-Point Protocol)。局域网的传输媒体,包括有线传输媒体和无线传输媒体两个大类,那么有线传输媒体有同轴电缆、双绞线和光纤;无线传输媒体有微波、红…