【锁定因子公式源码】【源码灰色】【oko源码】jvmcms源码

时间:2024-12-22 18:54:48 分类:源码混淆的语言 来源:穿越火线压枪源码

1.这究竟是源码为什么呢?都说JVM能实际使用的内存比-Xmx指定的少,头大
2.如何了解CMS的垃圾碎片率

jvmcms源码

这究竟是为什么呢?都说JVM能实际使用的内存比-Xmx指定的少,头大

       这确实是个挺奇怪的问题,特别是源码当最常出现的几种解释理由都被排除后,看来JVM并没有耍一些明显的源码小花招:

       要弄清楚这个问题的第一步就是要明白这些工具的实现原理。通过标准APIs,源码锁定因子公式源码我们可以用以下简单语句得到可使用的内存信息。

       而且确实,源码现有检测工具底层也是源码用这个语句来进行检测。要解决这个问题,源码首先我们需要一个可重复使用的源码测试用例。因此,源码我写了下面这段代码:

       这段代码通过将new int[1__]置于一个循环中来不断分配内存给程序,源码然后监测JVM运行期的源码源码灰色当前可用内存。当程序监测到可用内存大小发生变化时,源码通过打印出Runtime.getRuntime().maxMemory()返回值来得到当前可用内存尺寸,源码输出类似下面语句:

       实际情况也确实如预估的源码那样,尽管我已经给JVM预先指定分配了2G对内存,源码在不知道为什么在运行期有M内存不见了。oko源码你大可以把 Runtime.getRuntime().maxMemory()的返回值2,,K 除以来转换成MB,那样你将得到1,M,正好和M差M。

       在成功重现了这个问题之后,我尝试用使用不同的gk源码GC算法,果然检测结果也不尽相同。

       除了G1算法刚好完整使用了我预指定分配的2G之外,其余每种GC算法似乎都不同程度地丢失了一些内存。

       现在我们就该看看在JVM的源代码中有没有关于这个问题的解释了。我在CollectedHeap这个类的源码开始源代码中找到了如下的解释:

       我不得不说这个答案藏得有点深,但是只要你有足够的好奇心,还是不难发现的:有时候,有一块Survivor区是不被计算到可用内存中的。

       明白这一点之后问题就好解决了。打开并查看GC logging 信息之后我们发现,在Serial,Parallel以及CMS算法回收过程中丢失的那些内存,尺寸刚好等于JVM从2G堆内存中划分给Survivor区内存的尺寸。例如,在上面的ParallelGC算法运行时,GC logging信息如下:

       由上面的信息可以看出,Eden区被分配了,K,两个Survivor区都被分配到了,K,老年代(Old space)则被分配了1,,K。把Eden区、老年代以及一个Survivor区的尺寸求和,刚好等于2,,K,说明丢失的那M(,K)确实就是剩下的那个Survivor区。

       总结而言,当JVM在运行时报告的可使用内存小于-Xmx指定的内存时,差值通常对应于一块Survivor区的大小。对于不同的GC算法,这个差值可能有所不同。

如何了解CMS的垃圾碎片率

        PrintFLSStatistics这个参考比较有用,因为CMS GC会有碎片问题,而随着碎片的越来越严重,GC性能会变差直到发生FullGC,而FullGC时STW通过会超过数秒,这对OLTP系统来说是致命的,通过这个参数可以在gc日志中输出free list方式分配内存后内存统计情况和碎片情况;

        从CompactibleFreeListSpace的描述可知CMS使用free list分配内存

        -- 源码摘自compactibleFreeListSpace.hpp:

        再看compactibleFreeListSpace.cpp中的 gc_prologue 和 gc_epilogue (prologue的中文意思是开场白,epilogue的中文意思是收场白,所以这两个方法可以理解为gc前和gc后),由两个方法的实现可知,如果JVM参数PrintFLSStatistics 不为0(负数也可以),那么每次GC前后都会调用reportFreeListStatistics()方法打印出free list的统计信息:

        再看reportFreeListStatistics的具体实现,分为两个部分来看:

        输出free list统计信息,gc日志中输出内容如下:

        Total Free Space:

        Max Chunk Size:

        Number of Blocks: 1

        Av. Block Size:

        Tree Height: 1

        如果JVM参数为PrintFLSStatistics 大于1,例如-XX:PrintFLSStatistics=2,那么还会输出IndexedFreeLists的统计信息,以及如下的gc日志,能够直观的看到碎片率,frag的值越大碎片化越严重,JVM的初始化时frag的值为0.,即没有任何碎片:

        为了查询碎片化率越来越严重的GC日志,笔者基于kafka 2.-1.1.1版本,对其GC参数进行了一些调整,从而引起不断CMS GC:

        接下来只需要启动一个kafka broker,然后利用kafka自带的压测脚本向broker发送1kw条消息(每条消息个字节):

        bin/kafka-run-class.sh org.apache.kafka.tools.ProducerPerformance --topic topic-afei-test --num-records --record-size --throughput -1 --producer-props acks=1 bootstrap.servers=.0.1.: buffer.memory= batch.size=

        由jstat可知,FGC非常严重,每2s就有好几次的FGC:

        再看gc日志,kafka默认开启了gc日志(位于:logs/kafkaServer-gc.log.0.current):