https://matt33.com/2018/07/28/jvm-cms/

阶段1:Initial Mark

stop-the-wolrd

标记那些直接被 GC root 引用或者被年轻代存活对象所引用的所有对象

这个过程是很快的,虚拟机在类加载和JIT编译时将维护一个OopMap用来存放对象引用

阶段2:并发标记

与用户的应用程序并发运行

根据上个阶段找到的 GC Roots ,遍历老年代,然后标记所有存活的对象

并不是老年代所有的存活对象都会被标记,因为在标记期间用户的程序可能会改变一些引用

阶段3:Concurrent Preclean

与应用的线程并发运行

这个阶段有两个动作:

1)在并发运行的过程中,一些对象的引用可能会发生变化,此时将包含这个对象的区域(Card)标记为 Dirty,这也就是 Card Marking。

2)那些能够从 Dirty 对象到达的对象也会被标记,这个标记做完之后,dirty card 标记就会被清除了

阶段4:Concurrent Abortable Preclean

与应用的线程并发运行

为了尽量承担 STW(stop-the-world)中最终标记阶段的工作。

这个阶段是在重复做很多相同的工作,直接满足一些条件(比如:重复迭代的次数、完成的工作量或者时钟时间等)不太清楚到底做了什么鬼?

阶段5:Final Remark

这个阶段会比前面的几个阶段更复杂一些,有时这里会有younggc,parNew 会发生stw,还有啊,这里也涉及到 类的卸载!

stop the word

标记所有老年代所有的存活对象,之前都是并发进行的,所以无论如何都得停一下下,不然一直在变,gc就是不准确的

经历过这五个阶段之后,老年代所有存活的对象都被标记过了,现在可以通过清除算法去清理那些老年代不再使用的对象。

阶段6:Concurrent Sweep

与用户的应用程序并发运行

清除那些没有被标记的对象,回收它们的占用空间。

阶段7:Concurrent Reset

与用户的应用程序并发运行

重设 CMS 内部的数据结构,为下次的 GC 做准备

1.什么样的对象能成为GCRoot?

栈或寄存器中引用的对象,还有静态变量

1.
对于僵死的类及类加载器的垃圾回收将在元数据使用达到“MaxMetaspaceSize”参数的设定值时进行。
适时地监控和调整元空间对于减小垃圾回收频率和减少延时是很有必要的。
持续的元空间垃圾回收说明,可能存在类、类加载器导致的内存泄漏或是大小设置不合适。
https://blog.csdn.net/u012834750/article/details/70160594
每日大量499 说明 fullgc频繁,为什么频繁?
因为开启了classUNloading,每次fullgc都会进行类卸载,
但jvm默认是开启这个参数的,说明正常情况下类卸载是不会引起问题的。
所以为什么fullgc频繁呢?是哪快内存满了引起fullgc?
从gc日志上看,是老年代满了,引起的fullgc
2.
为什么扫描类卸载的时间长?
3.
-XX:CMSInitiatingOccupancyFraction
触发cms的空间占用百分比
4.
如何对永久代或元空间gc?
5.
-XX:CompressedClassSpaceSize 开启类指针压缩,这时候Klass存到 Klass MetaSpace中,
-XX:CompressedClassSpaceSize 开启指针压缩后,这个参数默认为1G,可以设置不超过32G的值
如果不开启指针压缩。klass将存在于NoKlass MetaSpace中
如果指针压缩好用,为什么jvm不是默认开启指针压缩呢?
6.
啥玩楞?
  -XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
  -XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集
7.
元空间的特点
充分利用了Java语言规范中的好处:类及相关的元数据的生命周期与类加载器的一致。
每个加载器有专门的存储空间
只进行线性分配
不会单独回收某个类
省掉了GC扫描 及压缩的时间 ??????
元空间里的对象的位置是固定的
如果GC发现某个类加载器不再存活了,会把相关的空间整个回收掉
8.
绝大多数的类元数据的空间都从本地内存中分配
用来描述类元数据的类(klasses)也被删除了
分元数据分配了多个虚拟内存空间
给每个类加载器分配一个内存块的列表。块的大小取决于类加载器的类型; sun/反射/代理对应的类加载器的块会小一些
归还内存块,释放内存块列表
一旦元空间的数据被清空了,虚拟内存的空间会被回收掉
减少碎片的策略
9.
final remark之前没有进行youngGC
10.
-XX:+UseCMSCompactAtFullCollection 开关参数(默认就是开启的)
用于在 CMS 收集器顶不住要进行 Full GC 时开启内存碎片的合并整理过程,
内存整理的过程是无法并发的,空间碎片问题没有了,但停顿时间不得不变长;
这是说每一次fullgc都会有内存碎片整理么???
11.
g1???

12.

所以,为什么机器开启几天之后才会逐渐出现499?

是因为内存碎片吧(Linux提出 伙伴系统 slab缓存,减少内存碎片)

Linux采用反碎片法减少篇内存碎片:

内核将已分配页划分为下面三种:

不可移动页:在内存中有固定位置,不可移动。核心内核分配的大多数内存属于该类别

可回收页:不能直接移动,但可以删除,内容可以从某些源重新生成。比如映射文件的数据

可移动页:可以随便移动的页。属于用户空间应用程序的页。这也说明了jvm确实是可以通过复制法减少内存碎片的。

--->P162《深入Linux内核架构》

13.

HugePages对内存使用密集的应用程序有好处,因为TLB只需处理较少的项,降低了TLB缓存失效的可能性,但是!分配巨型页面需要连续的空闲物理内存!--->P162 《深入Linux内核架构》

14.

未使用区是分配新内存空间的预备区域。对于普通进程来说,这个区域被可用于堆和栈空间的申请及释放,每次堆内存分配都会使用这个区 域,因此大小变动频繁;对于JVM进程来说,调整堆大小及线程栈时会使用该区域,而堆大小一般较少调整,因此大小相对稳定。操作系统会动态调整这个区域的 大小,并且这个区域通常并没有被分配实际的物理内存,只是允许进程在这个区域申请堆或栈空间。

https://zhuanlan.zhihu.com/p/61049063?utm_source=wechat_session&utm_medium=social&utm_oi=645188740205776896

15.

AMM和HugePages不兼容。

jvm——CMS 垃圾回收器(未完)的更多相关文章

  1. JVM七大垃圾回收器上篇Serial、ParNeW、Parallel Scavenge、 Serial Old、 Parallel Old、 CMS、 G1

    GC逻辑分类 垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商.不同版本的JVM来实现. 由于JDK的版本处于高速迭代过程中,因此Java发展至今已经衍生了众多的GC版本. 从不同角度分析垃圾收 ...

  2. 【JVM】垃圾回收器总结(2)——七种垃圾回收器类型

    七种垃圾回收器类型 GC的约定参数 DefNew——Default New Generation Tenured——Serial Old ParNew——Parallel New Generation ...

  3. JVM七大垃圾回收器下篇G1(Garbage First)

    G1回收器:区域化分代式 既然我们已经有了前面几个强大的GC,为什么还要发布Garbage First (G1)GC?  原因就在于应用程序所应对的业务越来越庞大.复杂,用户越来越多,没有GC就不能保 ...

  4. 探索ParNew和CMS垃圾回收器

    前言 上篇文章我们一起分析了JVM的垃圾回收机制,了解了新生代的内存模型,老年代的空间分配担保原则,并简单的介绍了几种垃圾回收器.详细内容小伙伴们可以去看一下我的上篇文章:秒懂JVM的垃圾回收机制. ...

  5. 关于 CMS 垃圾回收器,你真的懂了吗?

    大家好,我是树哥. 前段时间有个小伙伴去面试,被问到了 CMS 垃圾回收器的详细内容,没答出来.实际上,CMS 垃圾回收器是回收器历史上很重要的一个节点,其开启了 GC 回收器关注 GC 停顿时间的历 ...

  6. 【JVM】CMS垃圾回收器

    一.简介 Concurrent Mark Sweep,是一种以获取最短回收停顿时间为目标的收集器,尤其重视服务的响应速度. CMS是老年代垃圾回收器,基于标记-清除算法实现.新生代默认使用ParNew ...

  7. jvm学习-垃圾回收器(四)

    说明 各种垃圾回收算法都有各自的优缺点.jvm也并没有只采用一种垃圾算法.并提供几种组合供我根据场景进行选择. jvm内存结构 Person p=new Person(); 1.程序里面创建一个对象会 ...

  8. 深入探究JVM之垃圾回收器

    @ 目录 前言 正文 一.垃圾收集算法 标记-复制 标记-清除 标记-整理 分代回收 二.常用的垃圾回收器 Serial/SerialOld ParNew Parallel Scavenge/Para ...

  9. 面试官:说一下JVM常用垃圾回收器的特点、优劣势、使用场景和参数设置

    今天去看牙医,他问我年级轻轻牙齿怎么磨损这么严重?我说,没有人点赞的这些年,我都是咬着牙过来的. Java中的垃圾回收器几乎是面试中的必考点,无论是面试初级,中级还是高级,总免不了要问一问垃圾回收器的 ...

随机推荐

  1. Dojo入门:DOM操作

      作为一款功能齐全的js工具包,dojo提供了统一的DOM操作方法. dojo.byId dojo.byId 函数使您可以通过 id 属性选择一个 DOM 节点.该函数是标准 document.ge ...

  2. 如何获取当前包名与activitity&&抓log

    若hi1:获取当前包名以及Activity (1)adb shell dumpsys activity | find "mFocusedActivity" (2)adb shell ...

  3. ffi模块——node调用动态链接库(.so/.dll文件)

    参考资料1:[https://www.npmjs.com/package/ffi] 参考资料2:[http://imweb.io/topic/57732fbef0a5487b05f325bf] 参考资 ...

  4. Platform区分不同平台

    用于区分平台 OS 属性 表示当前的平台类型.只有 ios 与 android 两个值.如可以使用为同一个属性在不同的平台上赋不同的值 const styles = StyleSheet.create ...

  5. cocos2dx[3.2](4) 入口类AppDelegate

    这是游戏程序的入口,主要用于游戏程序的逻辑初始化,并创建运行程序的入口界面(即第一个游戏界面场景). 里面有三个方法: // applicationDidFinishLaunching(); //逻辑 ...

  6. 关于glog使用中遇到的问题

    项目中需要打log,当初看到glog,觉得google出品应该差不了,而且简单易用,库不是很大,就选择他了. 但是在使用中还真的发现一些不顺手和库设计上的问题,反正和我的使用习惯有点不一样. 设置lo ...

  7. 【DSP开发】ccsv6添加simulator功能

    ccsv5更新到ccsv6后,ti去掉了simulator功能,具体的说法是"CCSv6 does NOT have any simulators. Texas Instruments is ...

  8. [转帖]Windows与Linux的命令行命令对比

    Windows与Linux的命令行命令对比 https://www.cnblogs.com/sztom/p/10785140.html * Windows不区分大小写,Linux区分大小写的. sn ...

  9. CentOS7之ssh-Xshell密钥认证登陆

    操作系统版本:CentOS Linux release 7.2.1511 (Core)   SSH版本:OpenSSH_6.6.1p1, OpenSSL 1.0.1e-fips 1.打开Xshell工 ...

  10. Java 使用JDBC连接查询操作数据

    import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.sql. ...