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. java:Review(Oracle-HTML-CSS)

    20170708_review: 1.oracle: 对表的操作: 使用命令行建立一张表:create table 表名 (列名 列名的类型 primarty key, ....); alter ta ...

  2. python文档的数据读取,把读取数据写入到新的表里

    目的:接口自动化过程需要从表格文件读取,然后把结果写到表格中.没有多余内容全部是精华! 读取文件1 读取文件2 代码如下图: # -*-coding:utf-8 -*-# Author:wangjun ...

  3. cocos2dx[3.2](3) 浅析CCDeprecated.h

    CCDeprecated.h中存放的都是2.x将要被抛弃的命名规范,主要包含类名.枚举类型. 虽然说2.x的这些命名规范被CCDeprecated.h保留了.但是为了彻底学习3.x的新特性,就必须要尽 ...

  4. ARM的编程模式及寄存器

    根据朱老师的课程及下面博客整理 http://blog.chinaunix.net/uid-20443992-id-5700979.html ARM 采用的是32位架构 ARM 约定: Byte : ...

  5. mysql——单表查询——其它整理示例00

    ), sname ), sage ), ssex ) ); ','zhaolei','1990-01-01','nan'); ','qiandian','1990-12-21','nan'); ',' ...

  6. Anaconda配置环境变量+创建虚拟环境+pycharm使用虚拟环境

    Anaconda配置环境变量+创建虚拟环境 配置环境变量 没有添加系统变量,所有系统根本识别不了conda命令,找不到位置,所以添加以下系统变量: 添加对应Anaconda环境变量:(以自己的安装路径 ...

  7. 洛谷 P4779 单源最短路径(标准版) 题解

    题面 这道题就是标准的堆优化dijkstra: 注意堆优化的dijkstra在出队时判断vis,而不是在更新时判断vis #include <bits/stdc++.h> using na ...

  8. 模板 - 强连通分量 - Kosaraju

    Kosaraju算法 O(n+m) vector<int> s; void dfs1(int u) { vis[u] = true; for (int v : g[u]) if (!vis ...

  9. allure 这么高大上的测试报告环境,5 分钟搞定

    allure 的测试报告是老板喜欢的样子.如果能用上 allure,干嘛还选择其他的测试报告类型呢?python 的 pytest 单元测试框架有 allure 的插件,可以很方便的在 python ...

  10. 2.学习Application

    2学习Application Application对象事件 名称 说明 Activated 当应用程序成为前台应用程序时触发 Deactivated 当应用程序不再是前台应用程序时触发 Dispat ...