`
sw1982
  • 浏览: 503970 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JVM调优-解决native heap持续增长

阅读更多

问题的提出,分析,请参考JNI——小心,内存怪兽出没

(简单的说起来,就是java进程占用了4G内存,但是折腾来折腾去,整个JVM的堆才100M上下,其余的内存凭空消失?刨根问底之后,原来是native heap占用了内存)

看完上面的问题,再来看解决方案:

 

 

 

目前看来,通过调整 JVM 参数来加大 GC 触发的频率是比较现实的一种方式。下面是一些分析过程:

 

一.       判断 Memonry 内存所属的区


通过 jconsole 可以看到 gc 信息,其中新生代的 scavenge 回收比较频繁,如果 Memonry 在这个区应该不存在长期得不到 gc 的情况

由此推测 Memory 应该是在 Tenured/old ,而这个区的内存回收次数恰好非常少。 当然参数优化的目标,就是加大 old 区的 gc 频率。

 

二.       观察 JVM 的堆参数配置

1. 默认配置下,堆的分配起始值为 126M ,最大 1.8G  


 

2. 观察 gc 前后 java 整个堆 的使用情况, gc 前大概占 130M, 远未达到默认设置下的内存容量


 

3. 进一步查看 old 区的内存 ,发现在 gc 前稳定在 90M

而默认参数初始分配 85M ,最大 1.3G ,显然很难触发到 GC


 

三.       解决问题

1. 首要的问题就是控制 JVM 对整个 heap 的大小分配:

 -Xmx300M    指定 jvm 的最大 heap 大小 ,

          -Xms40M   指定 jvm 的最小 heap 大小 ,

 

2. 在减小了整个堆的前提下,优化 NewRatio 这个参数 ( 指定 jvm Old Generation heap size New Generation 的比例 )

            将默认的 NewRatio=2 更改为更符合业务实际内存使用比例的  -XX:NewRatio=1 

           减小了 old 区的比例,更容易触发 gc

 

         3. 另外一个猜测的可行方案:(有待验证)

启用 jvm 中的 gc 参数 -XX:MaxGCPauseMillis=<nnn>

这个参数的大概含义就是,让每次 gc 的时间不超过参数 nnn 。那么 nn 减少的时候,必然会增加到 gc 的次数,来换取每次 gc 的速度。

通过下图的数据可以求出,每次 old 区的 gc 平均耗时 34.7ms 那么可以   -XX:MaxGCPauseMillis=28 ,也许会增加到 gc 频率。


 

 

上述 4 个标红参数已经添加 ,观察几天得到的结论是,比较好的解决了这个问题。

====================================================================

分割线:下面是调优后的观察:

 

可以看到整个内存呈波动结构,Java的堆从20M--》60M就触发一次old区的gc。

下面看看GC的情况: MarkSweep是old区的gc策略,大概2个小时会触发一次,每次耗时

3194/112=28.5178ms,不会对应用产生明显的停摆,并且也验证了MaxGCPauseMillis参数的作用


 

 

  • 大小: 46.3 KB
  • 大小: 49.2 KB
  • 大小: 122.7 KB
  • 大小: 61.5 KB
  • 大小: 31 KB
  • 大小: 3.9 KB
  • 大小: 10.1 KB
2
1
分享到:
评论
6 楼 tictac 2011-06-09  
beneo 写道
sw1982 写道
beneo 写道
我感觉很奇怪,native heap为啥会在old区,但是jvm heap 却不显示出来。。不明白不明白

这个问题就看开头引用了同事的一篇文章分析。 native heap是不属于JVM堆管理的,但是产生natvie heap对象的引用类又出现在JVM的heap中,并且长期得不到gc处理。


那这完全变成了如何让OLD代更快GC了。。那就有些无聊了。。

设置:-XX:MaxDirectMemorySize值,可以吗?
5 楼 beneo 2010-07-30  
宋兄弟的这文章很赞
4 楼 beneo 2010-07-30  
sw1982 写道
beneo 写道
我感觉很奇怪,native heap为啥会在old区,但是jvm heap 却不显示出来。。不明白不明白

这个问题就看开头引用了同事的一篇文章分析。 native heap是不属于JVM堆管理的,但是产生natvie heap对象的引用类又出现在JVM的heap中,并且长期得不到gc处理。


那这完全变成了如何让OLD代更快GC了。。那就有些无聊了。。
3 楼 sw1982 2010-07-30  
beneo 写道
我感觉很奇怪,native heap为啥会在old区,但是jvm heap 却不显示出来。。不明白不明白

这个问题就看开头引用了同事的一篇文章分析。 native heap是不属于JVM堆管理的,但是产生natvie heap对象的引用类又出现在JVM的heap中,并且长期得不到gc处理。
2 楼 beneo 2010-07-30  
我感觉很奇怪,native heap为啥会在old区,但是jvm heap 却不显示出来。。不明白不明白
1 楼 beneo 2010-07-30  
好文章,第一次知道有个native heap

为什么要配置成full gc呢??丢到Eden或者S(2)就消灭了岂不是更好

相关推荐

Global site tag (gtag.js) - Google Analytics