皮皮网

【掌中云源码sina】【easyweb官网源码】【编译spring源码鲁班】jvmcms源码

时间:2024-11-29 23:20:51 分类:休闲 来源:苹果钓鱼id源码

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

jvmcms源码

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

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

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

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

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

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

       在成功重现了这个问题之后,我尝试用使用不同的票务商城php源码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):

copyright © 2016 powered by 皮皮网   sitemap