简介

分代垃圾回收器在进行minor GC的时候会发生什么操作呢?有没有什么提高效率的手段呢?今天我们和小师妹一起来了解一下垃圾回收中的Dirty cards和PLAB

分代收集器中的空间划分

小师妹:F师兄,能再讲讲分代垃圾收集器中的空间划分吗?

分代垃圾回收器中的Eden,Old和Survivor space几个大家应该都很熟悉的分代技术。

Young Gen被划分为1个Eden Space和2个Suvivor Space。当对象刚刚被创建的时候,是放在Eden space。

当Eden space满的时候,就会触发minor GC。会扫描Eden Space和一个Suvivor Space。如果在垃圾回收的时候发现Eden Space中的对象仍然有效,则会将其复制到另外一个Suvivor Space。

就这样不断的扫描,最后经过多次扫描发现仍然有效的对象会被放入Old Gen表示其生命周期比较长,可以减少垃圾回收时间。

Write barrier和Dirty cards

小师妹:F师兄,minor GC的时候,要将对象从Eden复制到Suvivor Space,从Suvivor Space中复制到Old space。GC是怎么知道哪些对象是要被回收,哪些是不用被回收的呢?

小师妹,GC这里用到了一项叫做Dirty cards的技术。

一般来说,新的对象是分配在Eden空间的。但是也有些对象是直接分配在Old space。

我们知道,GC的扫描是从一些根对象开始的,这些Root对象包括:正在执行的方法中的本地对象和输入参数。活动的线程,加载类中的static字段和JNI引用。

而这些根对象,一般都是存储在old space中的。

通常来说old space的空间都会比较大。每次要要找到Eden和suvivor Space中哪些对象不再被引用,需要扫描整个old space肯定是不可取的。

所以JVM在这里引入了Write barrier的技术。HotSpot中有两种Write barrier,一种就是今天我们要讲的Dirty cards,另外一种就是snapshot-at-the-beginning (SATB)。 SATB通常用在G1垃圾回收器中,这里我们先不做深入的讨论。

我们看下上图中的Dirty cards的使用。

Dirty cards说起来很简单,就是每当有程序对引用进行修改的时候,我们都会在一个Dirty cards的空间记录一下被修改的memory page。

这样在minor GC的时候,当引用的对象被修改了之后,我们会同步修改对应的Dirty cards。这样每次扫描old space的时候,只需要选择那些标记为Dirty cards的对象就可以了,避免了全局扫描。

PLAB

小师妹,F师兄,你讲的好像很有道理的样子,上次你讲到我们在Eden空间分配对象的,为了提升分配的效率,使用了TLAB的计算。那么在对象从Eden空间提升到Suvivor Space和old Space的时候有没有同样的技术呢?

当然有的,这个技术就叫做PLAB( promotion local allocation buffer)。每一个线程在survival space和old space中都一个PLAB。在提升的时候,可以避免多线程的竞争,从而提升效率。

我们可以使用-XX:+AlwaysTenure 将对象直接从Eden space提升到old space。

我们可以使用-XX:+PrintOldPLAB来输出OldPLAB的信息。

old space分配对象

小师妹:F师兄,刚刚你讲到新分配的对象可以直接在Old space,一般什么对象可以这样分配呢?

这个很好理解,如果你分配对象大小超过了Eden space的大小,是不是就只有old space可以分配对象了?

小师妹:对的,但是一般来说也不会使用这么大的对象吧。

对的,我们可以通过设置-XX:PretenureSizeThreshold=n 来指定对象的大小,如果对象大小大于n,那么就直接在old space分配。

注意,如果这个对象的大小比TLPB要小,那么会首先在TLPB中分配。所以使用的时候要注意限制TLPB的大小。

总结

GC的运行是一个比较复杂的过程,大家可以细细体会。本文如果有什么谬误之处,欢迎微信我指正。谢谢大家。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jvm-dirty-card-plab/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

小师妹学JVM之:Dirty cards和PLAB的更多相关文章

  1. 小师妹学JVM之:JIT中的PrintAssembly

    目录 简介 使用PrintAssembly 输出过滤 总结 简介 想不想了解JVM最最底层的运行机制?想不想从本质上理解java代码的执行过程?想不想对你的代码进行进一步的优化和性能提升? 如果你的回 ...

  2. 小师妹学JVM之:cache line对代码性能的影响

    目录 简介 一个奇怪的现象 两个问题的答案 CPU cache line inc 和 add 总结 简介 读万卷书不如行万里路,讲了这么多assembly和JVM的原理与优化,今天我们来点不一样的实战 ...

  3. 小师妹学JVM之:JVM的架构和执行过程

    目录 简介 JVM是一种标准 java程序的执行顺序 JVM的架构 类加载系统 运行时数据区域 执行引擎 总结 简介 JVM也叫Java Virtual Machine,它是java程序运行的基础,负 ...

  4. 小师妹学JVM之:GC的垃圾回收算法

    目录 简介 对象的生命周期 垃圾回收算法 Mark and sweep Concurrent mark sweep (CMS) Serial garbage collection Parallel g ...

  5. 小师妹学JVM之:深入理解JIT和编译优化-你看不懂系列

    目录 简介 JIT编译器 Tiered Compilation分层编译 OSR(On-Stack Replacement) Deoptimization 常见的编译优化举例 Inlining内联 Br ...

  6. 小师妹学JVM之:JDK14中JVM的性能优化

    目录 简介 String压缩 分层编译(Tiered Compilation) Code Cache分层 新的JIT编译器Graal 前置编译 压缩对象指针 Zero-Based 压缩指针 Escap ...

  7. 小师妹学JVM之:JIT中的LogCompilation

    目录 简介 LogCompilation简介 LogCompilation的使用 解析LogCompilation文件 总结 简介 我们知道在JVM中为了加快编译速度,引入了JIT即时编译的功能.那么 ...

  8. 小师妹学JVM之:JIT中的PrintCompilation

    目录 简介 PrintCompilation 分析PrintCompilation的结果 总结 简介 上篇文章我们讲到了JIT中的LogCompilation,将编译的日志都收集起来,存到日志文件里面 ...

  9. 小师妹学JVM之:java的字节码byte code简介

    目录 简介 Byte Code的作用 查看Byte Code字节码 java Byte Code是怎么工作的 总结 简介 Byte Code也叫做字节码,是连接java源代码和JVM的桥梁,源代码编译 ...

随机推荐

  1. xlua中lua对象到c#对象的转型

    lua中的类型 基础类型 #define LUA_TNIL 0 #define LUA_TBOOLEAN 1 #define LUA_TLIGHTUSERDATA 2 #define LUA_TNUM ...

  2. count(1) AND count(*) 对比

    相信很多小伙伴都想知道count(1) 和 count(*) 的速度问题 ,今天我给大家做一下测试.我这里测试的是MySql数据库 声明:测试之前 我数据库表里面有100万条数据.我们先来测试coun ...

  3. CGAL 获取相关功能的依赖头文件

    CGAL 获取相关功能的依赖头文件 由于CGAL是header include only.只需要头文件就可以实现相关的功能.有时候为了实现一个简单的功能, 在研究具体实现的时候能够知道这个功能对应的头 ...

  4. 第m大的身份证号码(局部排序代全局、结构体排序)

    第m大的身份证号码(点击) 时间限制: 1 Sec  内存限制: 128 MB                                                             ...

  5. 包子凑数(dp 0-1、完全背包)【背包问题】

    包子凑数(蓝桥杯) 感谢:@ Statusrank 题目链接(点击) 题目描述 小明几乎每天早晨都会在一家包子铺吃早餐.他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子.每种蒸笼都有非常多 ...

  6. (六)TestNg中的软断言和硬断言

    原文链接:https://cloud.tencent.com/developer/article/1479172 前言 在执行自动化测试脚本的时候,我们需要自动判断测试脚本执行完成后的实际结果是否与预 ...

  7. Dubbo——服务调用过程

    文章目录 引言 服务的交互 服务降级 集群容错 服务调用 服务端接收请求 总结 引言 经过之前文章的铺垫,现在可以来分析服务的交互调用过程了. 服务的交互 服务降级 从名字上看我们不难理解MockCl ...

  8. 【Spring注解驱动开发】如何使用@Bean注解指定初始化和销毁的方法?看这一篇就够了!!

    写在前面 在[String注解驱动开发专题]中,前面的文章我们主要讲了有关于如何向Spring容器中注册bean的知识,大家可以到[String注解驱动开发专题]中系统学习.接下来,我们继续肝Spri ...

  9. npm设置为淘宝镜像地址

    1. npm设置为淘宝镜像 $npm config set registry https://registry.npm.taobao.org 2. 检查一下 $npm config get regis ...

  10. Java将日期转化为大写格式(阿拉伯大写数字)

    效果: 代码部分: public static void main(String[] args) { SimpleDateFormat sdf=new SimpleDateFormat("y ...