JVM系列(九) 垃圾收集器之 Serial / Serial Old

2023-10-27

回收期演变及概览

前面我们讲了很多 垃圾收集的原理和知识点,下面我们针对各种垃圾收集器进行JVM调优,JVM调优其实都是根据对应的垃圾收集器特性而去做调整和优化。

不同垃圾收集器的产生总体可以划分为几个阶段。。

  • 第一阶段:单线程收集时代(Serial和Serial Old)
  • 第二阶段:多线程收集时代(Parallel Scanvenge 和Parallel Old)
  • 第三阶段:并发收集时代(ParNew和CMS)
  • 第四阶段:通用并发收集时代(G1)

实际项目中并不会设置唯一的收集器,有可能是几种混用,比如ParNew其实和Paralled Sacanvenge差不多,但是就因为ParNew是唯一的可以和CMS配合进行新生代收集的收集器,所以它就经常和CMS一起使用

  • 新生代收集器: Serial、ParNew、Parallel Scavenge;
  • 老年代收集器: Serial Old、CMS、Parallel Old;
  • 通用收集器: G1;

收集器常用组合:

  1. Serial + Serial Old
  2. Parallel Scavenge + Parallel Old
  3. ParNew + CMS配合
  4. G1(不需要组合其他收集器)

下面我们会一个一个分析 如何使用及如何调优,对于 Serial + Serial Old 这个单线程垃圾收集器几乎不会再实际项目中使用,我们简单了解一下即可

1.Serial/Serial Old
  • Serial 年轻代,单线程收集器,最基本,历史最悠久的垃圾收集器
  • Serial Old 老年代, 单线程收集器

为啥它没人用?

  • 因为他是单线程,“单线程” 的意义不仅仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工作
  • 更重要的是它在进行垃圾收集工作的时候必须暂停其他所有的工作线程( “Stop The World” ),直到它收集结束。

Serial收集器没有线程交互的开销,可以获得很高的单线程收集效率。但是屁用没有,没有人实战中会开一个单线程专门收集垃圾而且还能忍受StopTheWorld

2.测试Serial/Serial Old 垃圾收集器

查看你自己的jdk使用的默认垃圾收集器,如果你是java8,而且没有在项目中指定垃圾收集器,那么他就是ParallelGC 并行垃圾收集器

#查看jdk版本 使用的默认垃圾收集器
java -XX:+PrintCommandLineFlags -version

打印日志

C:\Users\jzj>java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=265507840 -XX:MaxHeapSize=4248125440 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

可以看到我的jdk默认的是 UseParallelGC

我们现在设置单线程收集器Serial/SerialOld

2.1 设置JVM参数 测试GC日志

设置JVM参数

-verbose:gc -XX:+UseSerialGC -Xmx30M  -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError 

单线程 Serial/SerialOld def new generation

  • 年轻代 def new generation
  • 伊甸区 eden space
  • Surviral from space区 from
  • Surviral to space区 to
  • 老年代 tenured generation
  • 元空间 Metaspace
2.2 JVM测试类

Jvm测试类,设置JVM最大堆30M, MyBigObj对象 每个5M, 创建3个对象, 看下GC内容

@Slf4j
public class JvmTest {

    static class MyBigObj {
        // 创建5M大小的字节数组
        private byte[] bytes = new byte[1024*1024*5];
    }

    public static void main(String[] args) throws Exception {

        //创建一个大对象

        MyBigObj big1 = new MyBigObj();
        MyBigObj big2 = new MyBigObj();
        MyBigObj big3 = new MyBigObj();

        System.gc();

        Thread.sleep(5000);

    }
}

打印GC日志

[GC (Allocation Failure) [DefNew: 7056K->1024K(9216K), 0.0025395 secs] 7056K->1466K(29696K), 0.0025691 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 6144K->0K(9216K), 0.0055420 secs] 6586K->6586K(29696K), 0.0055680 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC (System.gc()) [Tenured: 6586K->11706K(20480K), 0.0063238 secs] 11706K->11706K(29696K), [Metaspace: 4672K->4672K(1056768K)], 0.0063757 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
Heap
 def new generation   total 9216K, used 731K [0x00000007be200000, 0x00000007bec00000, 0x00000007bec00000)
  eden space 8192K,   8% used [0x00000007be200000, 0x00000007be2b6c30, 0x00000007bea00000)
  from space 1024K,   0% used [0x00000007bea00000, 0x00000007bea00000, 0x00000007beb00000)
  to   space 1024K,   0% used [0x00000007beb00000, 0x00000007beb00000, 0x00000007bec00000)
 tenured generation   total 20480K, used 11706K [0x00000007bec00000, 0x00000007c0000000, 0x00000007c0000000)
   the space 20480K,  57% used [0x00000007bec00000, 0x00000007bf76e8c0, 0x00000007bf76ea00, 0x00000007c0000000)
 Metaspace       used 4782K, capacity 5064K, committed 5248K, reserved 1056768K
  class space    used 530K, capacity 564K, committed 640K, reserved 1048576K

堆一共JVM设置 30M

  • 年轻/老年 1:2, 所以年轻代 大概 10M , 老年代大概20M
  • 年轻代中区分 eden:from:to, 8:1:1, 所以年轻代可用 大概9M左右
  • def new generation total 9216K =9M 年轻代可用
  • eden space 8192K, eden区 8M
  • from space 1024K, from 1M
  • to space 1024K, to 1M
  • tenured generation total 20480K=20M 老年代
  • Metaspace 元空间 5M左右
3. GC日志分析
GC日志参数 含义
GC (Allocation Failure) GC引起原因是年轻代没有足够空间存储新数据
Full GC (System.gc() FullGC引起原因是老年代空间不足,gc垃圾回收后依旧存在大量对象,无法回收
DefNew 新生代,这个名称由收集器决定。Serial 收集器的新生代
Tenured Seriale Old 收集器配套的老年代
Metaspace 元空间 Java8 之后的永久代变为元空间
#第一行分析
[GC (Allocation Failure) [DefNew: 7056K->1024K(9216K), 0.0025395 secs] 7056K->1466K(29696K), 0.0025691 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
  • [GC (Allocation Failure) 发生GC
  • [DefNew: 7056K->1024K(9216K), 0.0025395 secs]
    • 发生在年轻代, 垃圾回收前 7056K, 垃圾回收后 1024K存留, 年轻代总容量 9216K
  • 7056K->1466K(29696K), 0.0025691 secs
    • gc前Java堆已使用容量7056K->gc后Java堆已使用容量1466K(Java堆的总容量29696K-已分配), DefNew 新生代回收gc耗时0.0025691 secs
#第二行分析
[Full GC (System.gc()) [Tenured: 6586K->11706K(20480K), 0.0063238 secs] 11706K->11706K(29696K), [Metaspace: 4672K->4672K(1056768K)], 0.0063757 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
  • [Full GC (System.gc()) 发生了FullGC, 发生了StopTheWorld 老年代发生GC
  • [Tenured: 6586K->11706K(20480K), 0.0063238 secs]
    • Tenured 老年代垃圾回收, 垃圾回收前6586K->垃圾回收后11706K, 老年代大小20480K, 回收耗时0.0063238 secs
  • 11706K->11706K(29696K)
    • gc前Java堆已使用容量11706K->gc后Java堆已使用容量11706K(Java堆的总容量29696K-已分配)
  • [Metaspace: 4672K->4672K(1056768K)] 元空间 回收前4672K, 回收后4672K, 总大小1056768K
  • 整个FullGC 耗时 0.0063757 secs

这就是 Serial/SerialOld 的垃圾回收机制及打印的GC日志,可以看到 采用Serial/SerialOld 的时候,他们的年轻代和老年代分别用DefNew 和 Tenured来代表, 不同的垃圾收集器采用不同的收集机制

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM系列(九) 垃圾收集器之 Serial / Serial Old 的相关文章

  • 读取文件并获取 key=value 而不使用 java.util.Properties

    我正在构建一个 RMI 游戏 客户端将加载一个包含一些键和值的文件 这些键和值将用于多个不同的对象 它是一个保存游戏文件 但我不能为此使用 java util Properties 它符合规范 我必须读取整个文件并忽略注释行和与某些类不相关
  • 正确配置JDK环境变量后仍然找不到java命令

    我在 Windows 虚拟机启动时安装 JDK 使用 cloudinit 用户数据将 PowerShell 脚本传输到 Windows 计算机 然后运行该脚本来安装 JDK softwares Get ItemProperty HKLM S
  • 获取jdbc中表依赖顺序

    我在 MySQL 数据库中有一组表 A B C D 依赖关系如下 B gt C gt A 和 D gt A 也就是说 A 有一个 PrimaryKey C 有一个外键指向 A 的主键 B 有一个外键指向 C 的主键 类似地 D 有一个外键指
  • 指纹奇异点检测

    我正在尝试确定指纹的核心点和增量点 我正在使用庞加莱指数方法 但我无法成功检测到这一点 而且我不明白为什么 First I divide the image in 15x15 blocks then I calculate the x an
  • 如何防止在 CXF Web 服务客户端中生成 JAXBElement

    我正在尝试使用 CXF 创建一个 Web 服务客户端来使用 WCF Web 服务 当我使用 wsdl2java 时 它生成具有 JAXBElement 类型而不是 String 的对象 我读到有关使用 jaxb bindings xml 文
  • 在 Android 中绘制一条带有弯曲边缘的线

    I am using canvas drawLine to draw some line in android but the lines are too sharp but i need a curved edges 这里的 1 是我所拥
  • java中队列的实现

    在 Java 中实现队列是一个非常常见的面试问题 我在网上冲浪 看到了许多实现 他们做了一些奇特的事情 比如实现队列接口和编写自己的addLast and removeFirst 方法 我的问题是我不能使用LinkedList 类并使用其预
  • 代码编译期间遇到警告消息“使用或覆盖已弃用的 API”

    我编译了我的程序并收到以下错误 我该如何解决呢 Note ClientThreadClients java uses or overrides a deprecated API Note Recompile with Xlint depre
  • 为什么一个线程会中断另一个线程[重复]

    这个问题在这里已经有答案了 在Java多线程应用程序中 我们处理InterruptedThreadException 如果另一个线程中断当前线程 则会抛出此异常 现在 当另一个线程知道它将导致异常时 它可能想要中断当前线程的原因是什么 很多
  • 如何屏蔽 Protobuf 中的某些字段

    我找不到一种方法来屏蔽 protobuf 结构中的某些字段 我确实阅读了有关 FieldMaskUtil 的内容并尝试了几个示例 但它似乎做了相反的操作 即复制 FieldMask 中提到的字段 这与我想要的不同 这是示例结构和相应的测试代
  • 更改 JTextPane 的大小

    我是Java新手 刚刚在StackOverflow中找到了这段代码 ResizeTextArea https stackoverflow com questions 9370561 enabling scroll bars when jte
  • JavaFx 中装饰且不可移动的舞台

    我想在 JavaFx 中创建一个装饰舞台 它也将不可移动 我正在从另一个控制器类创建这个阶段 我能够创造和展示舞台 但它是自由移动的 我怎样才能创建这个 非常感谢帮助和建议 我把打开新关卡的方法贴出来 private void addRec
  • 如何在命令提示符中检查 JAVA_OPTS 值?

    我们的应用程序部署 JBoss 服务器然后抛出错误 PermGen space 然后在 jboss bat 和配置文件中设置 permgen 变量中的 java OPTS JAVA OPTs 中是否有值 assige 如何检查 如何在命令提
  • Java 中 static 关键字如何工作?

    我正在阅读Java教程 http docs oracle com javase tutorial index html从一开始我就有一个问题static字段或变量上的关键字 作为Java said here http docs oracle
  • 尝试在空对象引用上调用虚拟方法“java.lang.String org.jsoup.nodes.Element.ownText()”

    我正在使用下面的代码来获取版本名称 from 应用商店通过使用 jsoup 我正在获取详细信息 但它引发了一些异常 我的代码是 public class ForceUpdateAsync extends AsyncTask
  • Netty中连接关闭后重新连接的最佳方法是什么

    简单场景 扩展 SimpleChannelUpstreamHandler 的较低级别的类 A 此类是发送消息和接收响应的主力 系统其他部分可以使用顶级类 B 来发送和接收消息 可以模拟同步和异步 此类创建 ClientBootstrap 设
  • 膨胀类片段 InflateException 二进制 XML 文件时出错

    我正在使用 Material Design 和 NavigationDrawer 布局等设计我的第一个应用程序 但我遇到了一个问题 该应用程序非常简单 它只显示文本 并且基于 Android Studio 中提供的模板 尝试启动我的应用程序
  • Jenkins 管道和 java.nio.file.* 方法的问题

    我正在尝试使用 java nio file 中的方法在 Jenkins 管道中执行一些基本文件操作 无论代码存在于哪个节点块中 代码都在主节点上执行 在管道中 我已经验证了各个节点块都是正确的 它们唯一地标识了特定的节点 但是 pathEx
  • java数据结构模拟数据树

    我需要帮助定义使用什么方法 我有一个 SOAP 响应 给我一个 xml 文件 我需要在屏幕上显示 3 个相关列表 当您在第一个列表中选择一个项目时 相应的选择将出现在第二个列表中 依此类推 我只对从 xml 流中提取数据后如何有效地组织数据
  • 当我在 Java 中输入 IP 时无法连接到我的服务器

    好的 我正在尝试学习 Java 客户端 服务器的内容 并且正在浏览教程代码 如下所示 当我将 localhost 更改为我的 IP 时 它会停止工作 请帮忙 编辑 127 0 0 1 似乎也可以工作 但不是我的真实IP Copyright

随机推荐

  • ifstream之seekg/tellg

    声明 我个人特别讨厌 收费专栏 关注博主才可阅读等行为 推崇知识自由分享 推崇开源精神 呼吁你一起加入 大家共同成长进步 在文件读写的时候 一般需要借助fstream来进行文件操作 常见的操作有seekg 和tellg 但是这两个函数有一些
  • 机器学习之——单变量线性回归

    线性回归 线性回归 Linear Regression 作为Machine Learning 整个课程的切入例子确实有独到的地方 以简单的例子为出发点 将学习任务的主干串起来 问题的建模可以简单如下图所示 线性回归可以分为单变量线性回归 L
  • media sdk 性能优化

    https software intel com sites default files m 2 0 a 7 9 28439 Intel Media SDK E4 B9 8B E4 BC 98 E5 8C 96 E6 8A 80 E6 9C
  • SQLServer开启远程连接

    一 在需要被远程连接的电脑客户端中打开命令提示符输入 ipconfig 找到IPV4地址 二 在SQLServer配置管理器中找到端口 三 1 打开 控制面板 2 打开 系统和安全 3 打开 WindowDefender防火墙 4 打开 高
  • C#中 Console方法介绍

    一般情况下 我们用来输入信息的方法主要是用到如下四个 1 console log 用于输出普通信息 2 console info 用于输出提示性信息 3 console error 用于输出错误信息 4 console warn 用于输出警
  • 20世纪最好的十大算法、算法笔记(2008-11-15 22:16:57、2011-04-21 19:29:05)

    Algorithm 算法 一词与9世纪的阿拉伯学者al Khwarizmi有关 他写的书 al jabr w al muqabalah 代数学 演变成为现在中学的代数教科书 Ad Khwarizmi强调求解问题的有条理的步骤 20世纪最好的
  • 启动虚拟机异常(完整版)——如果已在 BIOS/固件设置中禁用 Intel VT-x,或主机自更改此设置后从未重新启动,则Intel VT-x处于禁用状态

    创建了Linux虚拟机 点击 开机 之后 报了这个错误 笔记本电脑 我的 联想天逸 笔记本电脑 许多键与其他的 比如 华硕笔记本电脑 不同 想在操作系统中按F2 要Fn加 减音量 才有F2的功能 我将这个思想带到 启动BIOS 中 害惨了我
  • vue 使用 wangeditor 富文本编辑器

    wangeditor 是一个轻量级 web 富文本编辑器 配置方便 使用简单 1 安装 wangeditor 终端安装 wangeditor 库 yarn add wangeditor editor 或者 npm install wange
  • 腾讯云数据库CDB技术演进之路

    IT168 专稿 本文根据 2016 第八届系统架构师大会 微信搜索SACC2013 关注系统架构师大会公众号 现场演讲嘉宾程彬老师分享内容整理而成 录音整理及文字编辑IT168 田晓旭 老鱼 嘉宾简介 程彬 腾讯基础架构部数据库研发负责人
  • SQLSERVR 转换为数字类型numeric时出现算数溢出错误

    SQLSERVR 转换为数字类型numeric时出现算数溢出错误 情况一 在SQLSERVER中 关于数据的计算可能会导致出现如下的错误 遇到这类问题 一般都是由于结果超过了这个字段的长度 个字段的属性的概念 create table T1
  • 教你怎么用Vulnhub来搭建环境

    0x01 前言 Vulnhub它是一个提供各种漏洞环境的平台 里面大部分的环境是要用VMware或者VirtualBox打开运行的 如果只是练习一些常见的漏洞可以看我另外两篇用Docker来搭建各种漏洞靶场 妈妈再也不用担心我没有靶场练习了
  • 递归实现全排列

    设 R r1 r2 rn 是需要排列的 N 个元素 Ri R ri 设集合 中的元素 全排列记 为 Perm X ri Perm X 表示在 全排列 Perm X 的每一个排列前加上前缀 ri 得到的全排列 例如在 Perm X 的排列为
  • [java]java使用AES加密解密 ,AES-128/192/256-ECB加密模式

    直接上代码 是在springboot下直接test的 import org apache commons codec binary Base64 import org junit Test import org junit runner R
  • 【Linux 驱动篇(四)】设备树

    文章目录 一 什么是设备树 二 DTS DTB 和 DTC 三 DTS 语法 1 dtsi 头文件 2 设备节点 3 标准属性 3 1 compatible 属性 3 2 model 属性 3 3 status 属性 3 4 address
  • 4种线程池详解

    要配置一个线程池是比较复杂的 尤其是对于线程池的原理不是很清楚的情况下 很有可能配置的线程池不是较优的 因此在Executors类里面提供了一些静态工厂 生成一些常用的线程池 文章目录 ExecutorService概述 newSingle
  • HttpComponents(Apache HttpComponents Client 4.1.3)通过代理访问网页的设置方法

    HttpClient httpclient new DefaultHttpClient 这里是设置代理服务器的地方 HttpHost proxy new HttpHost 10 10 228 43 808 http httpclient g
  • win7 升级到 win10

    摘要 项目上遇到一个问题 客户提供一个软件在设备上点击运行后 转圈加载下就没有下文了 但是其他的软件又能正常运行 尝试了漏洞修护 系统修护 兼容性运行 管理员运行 32位兼容性进程检测等方式都不行 只能采取将win7升级到win10一试 在
  • vue学习,v-for不渲染

    最近在学习vue 使用axios v for做个搜索天气的小练习 发现只有第一次搜索有数据 改变数组后vue for不渲染 但使用console log可以看到数据确实更新了 使用this forceUpdate 这个不起作用 没办法了 只
  • Python实现桶排序

    Python实现桶排序 一 桶排序简介 桶排序 Bucket sort 是一种通过分桶和合并实现的排序算法 又被称为箱排序 桶排序先将数据分到有限数量的桶里 然后对每一个桶内的数据进行排序 桶内排序可以使用任何一种排序算法 如快速排序 最后
  • JVM系列(九) 垃圾收集器之 Serial / Serial Old

    回收期演变及概览 前面我们讲了很多 垃圾收集的原理和知识点 下面我们针对各种垃圾收集器进行JVM调优 JVM调优其实都是根据对应的垃圾收集器特性而去做调整和优化 不同垃圾收集器的产生总体可以划分为几个阶段 第一阶段 单线程收集时代 Seri