简介

java程序员都听说过GC,大家也都知道GC的目的是扫描堆空间,然后将那些标记为删除的对象从堆空间释放,以提升可用的堆空间。今天我们会来探讨一下隐藏在GC背后的一个小秘密Safepoints。

GC的垃圾回收器

小师妹:F师兄,GC的垃圾回收器的种类为什么会有这么多呀?使用起来不是很麻烦。并且我听说CMS在JDK9zhong已经被废弃了。

小师妹,这么多垃圾回收器实际是在JVM的发展过程中建立起来的,在之前的文章中,我们讲到了目前的GC回收器有这样几种。

  1. 基于分代技术的回收器

Concurrent mark sweep (CMS) ,CMS是mark and swap的升级版本,它使用多个线程来对heap区域进行扫描,从而提升效率。

由于CMS的参数复杂性和性能问题,CMS已经在JDK9中被废弃了。

Serial garbage collection,使用单一的线程来进行垃圾回收操作,其好处就是不需要和其他的线程进行交互。如果你是单核的CPU,那么最好就是选择Serial garbage collection,因为你不能充分利用多核的好处。同样的它也常常用在比较小型的项目中。

Parallel garbage collection,如果你是多核处理器,那么Parallel GC可能是你的选择。

Parallel GC是JDK8中的默认GC。而在JDK9之后, G1是默认的GC。

G1 garbage collection,G1=Garbage First,它是为替换CMS而生的,最早出现在java7中。

G1将heap区域划分成为多个更小的区域,每个小区域都被标记成为young generation 或者old generation。从而运行GC在更小的范围里运行,而不是影响整个heap区域。

  1. 非基于分代技术的回收器

Z Garbage Collection,ZGC是一个可扩展的,低延迟的GC。ZGC是并发的,而且不需要停止正在运行的线程。

ZGC是在JDK11中引入的。

当然还有正在研发中的其他GC。

分代回收器中的问题

小师妹:F师兄,分代回收器不好吗?为什么还有新的ZGC等基于非分代技术的回收器?

分代垃圾回收器中有一个非常常见的现象就是"Stop The World"。什么是Stop the world呢?

就是说在GC的时候,为了进行垃圾回收,需要所有的线程都要暂停执行。所有的线程都暂停执行。

当然G1虽然是基于分代技术,但是G1实际上是不会"Stop The World"的。

JVM定义了一些Root对象,从这些对象开始,找出他们引用的对象,组成一个对象图。所有在这个图里面的对象都是有效的对象,反之不在对象图中的对象就应该被回收。有效的对象将会被Mark为alive。

这些Root对象包括:正在执行的方法中的本地对象和输入参数。活动的线程,加载类中的static字段和JNI引用。

safepoints

为了实现STW的功能,JVM需要提供一个机制,让所有的线程可以在某一个时刻同时停下来。这个停下来的时刻就叫做safepoints。

注意,这些停下来的线程不包括运行native code的线程。因为这些线程是不属于JVM管理的。

JVM中的代码执行其实有两种方式,一种是JIT编译成为机器码,一种是解释执行。

在JIT中,直接将检查代码编译进入了机器码中。通过设置相应的标记位,从而在线程运行的过程中执行暂停的指令。

还是举一个上篇文章中我们提到的JMH的例子:

@Benchmark
public void test1() {
int length = array.length;
for (int i = 0; i < length; i=i+1)
array[i] ++;
}

我们看一下它的assembly code:

可以看到其中有个test的指令,这个test指令就是生成的safe points。

通过设置标志位,就可以在线程运行时执行暂停操作。

如果是解释执行的话,JVM保存了两个字节码的调度table,当需要safepoint的时候,JVM就进行table的切换,从而开启safepoint。

safepoint一般用在什么地方

一般情况下,GC,JIT的反代码优化,刷新code cache,类重定义 ,偏向锁撤销和其他的一些debug操作。

我们可以通过使用-XX:+PrintGCApplicationStoppedTime来print safepints的暂停时间。

-XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1这两个参数可以强制JVM打印safepoint的一些统计信息。

总结

Safepoint是垃圾回收中一个非常重要的概念,希望大家能够有所了解。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jvm-jit-safepoints/

本文来源:flydean的博客

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

小师妹学JVM之:JVM中的Safepoints的更多相关文章

  1. 小师妹学JavaIO之:NIO中那些奇怪的Buffer

    目录 简介 Buffer的分类 Big Endian 和 Little Endian aligned内存对齐 总结 简介 妖魔鬼怪快快显形,今天F师兄帮助小师妹来斩妖除魔啦,什么BufferB,Buf ...

  2. 小师妹学JavaIO之:NIO中Channel的妙用

    目录 简介 Channel的分类 FileChannel Selector和Channel DatagramChannel SocketChannel ServerSocketChannel Asyn ...

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

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

  4. 小师妹学IO系列文章集合-附PDF下载

    目录 第一章 IO的本质 IO的本质 DMA和虚拟地址空间 IO的分类 IO和NIO的区别 总结 第二章 try with和它的底层原理 简介 IO关闭的问题 使用try with resource ...

  5. 小师妹学JavaIO之:文件系统和WatchService

    目录 简介 监控的痛点 WatchService和文件系统 WatchSerice的使用和实现本质 总结 简介 小师妹这次遇到了监控文件变化的问题,F师兄给小师妹介绍了JDK7 nio中引入的Watc ...

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

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

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

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

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

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

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

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

  10. 小师妹学JVM之:JIT中的PrintAssembly续集

    目录 简介 JDK8和JDK14中的PrintAssembly JDK8中使用Assembly JDK14中的Assembly 在JMH中使用Assembly 总结 简介 上篇文章和小师妹一起介绍了P ...

随机推荐

  1. jstl中<c:if>标签属性用法

    今天用jstl+el从session域中获取属性,遇到了问题 org.apache.jasper.JasperException: <h3>Validation error message ...

  2. 小技巧:如何用 Chrome 将 SVG 转成 PNG

    怎么把 SVG 转成 PNG ?用 Chrome 吧,非常好用,还能设定自己想要的尺寸. 什么是 SVG ? SVG (Scalable Vector Graphics,可缩放矢量图形) 是基于 XM ...

  3. javaCV开发详解之12:视频转apng动态图片实现,支持透明通道,也支持摄像机、桌面屏幕、流媒体等视频源转apng动态图

    wjavaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG. ...

  4. mac 排查被占端口

    Last login: Wed Sep :: on ttys000 sam:~ sam$ sudo lsof -i : Password: COMMAND PID USER FD TYPE DEVIC ...

  5. Centos7 systemctl添加自定义系统开机服务

    Centos7的服务systemctl脚本存放在: /usr/lib/systemd/ 有系统(system)和用户(user)之分,需要开机不登陆就能运行的程序,存下系统服务里,即:/usr/lib ...

  6. [原创][开源] SunnyUI.Net 开发日志:UIBarChart 坐标轴刻度取值算法

    _ 在开发UIBarChart的过程中,需要绘制Y轴的刻度,数据作图时,纵横坐标轴刻度范围及刻度值的取法,很大程度上取决于数据的分布.对某一组数据,我们很容易就能知道如何选取这些值才能使图画得漂亮.但 ...

  7. 完美解决PYQT5登录界面跳转主界面方法

    该问题,有很多种方法,但是很多方法要么这个有问题,要么那个有问题,最后终于找到一种没问题的方法.记录一下: Login.py(登录窗口)文件 import sys from PyQt5 import ...

  8. C++ Primer Plus(一)

    完整阅读C++ Primer Plus 系统重新学习C++语言部分,记录重要但易被忽略的,关键但易被遗忘的. 预备 1.C++相对于C增加了最关键的两项,面向对象和范型编程. 处理数据 2.对于变量明 ...

  9. CODING DevOps 系列第三课:云计算、云原生模式下 DevOps 的建设

    本文首先会和大家分享当前整个应用生命周期的演变历程,然后讲解云计算模式下 DevOps 建设包含的过程.流程规范和标准,最后讲解云原生时代到来会带来哪些改变,以及标准化的建设会有哪些改变和突破. 应用 ...

  10. Jmeter 测试接口

    创建线程组 添加HTTP请求 查看结果树