JVM的FullGC优化实战(一) - 高飞网
1110 人阅读

JVM的FullGC优化实战(一)

2016-01-12 15:00:20

    今天我们的城市站项目(city-web)在早上9点钟出现了多次FullGC,导致网站报警严重。如下图示

    从上图可以看到,FullGC非常频繁,一分钟之内达到20多次,这种情况下几乎等于程序宕机,因为在FullGC的时候,几乎无法对外提供服务。通过监控视图也证明了这一点:

    从上图可见,我们的项目是6台集群,“假死”了四台,都是因为FullGC的原因,当然“假死”一会儿后,也会随着FullGC的结束再次“活”过来。

    同时,老年代对象表现的非常糟糕,GC以后,立马再涨上来。说明程序中对老年代对象的对象的控制出现了问题。

于是我们让运维dump了当时的内存city.hprof,用eclipse的Memory Analyzer Tool打开分析内存,分析结果是:


    接着点击Leak Suspects链接,查询具体的内存分析报表:


上图看到,有80%的内存被StandardManager对象占用了。而内存被一个ConcurrentHashMap的实例堆积而来。建议查询的关键字是下面三个:

org.apache.catalina.loader.StandardClassLoader @ 0x77805f3c0
org.apache.catalina.session.StandardManager
java.util.concurrent.ConcurrentHashMap$Segment[]

然后点Details链接:


    查看源码(apache-tomcat-7.0.67-src.zip)得知,在StandardManager的父类中,确实存在一个老年代的对象,是用ConcurrentHashMap来存储的,如下:

/**
     * The set of currently active Sessions for this Manager, keyed by
     * session identifier.
     */
    protected Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();


主流互联网会话管理机制都是cookies+cache,那么代码里哪里会用到Session呢?查看代码暂时没有发现,这里有一篇文章:一次由于垃圾session分配造成的内存惨案。其中讲到,由于Session创建过多,造成了session的大量堆积,导致内存泄露。目前线上环境的session的超时时间依然是30分钟,按照上面文章中介绍的办法,把session的超时时间设置为3分钟。

随后观察,FullGC依然会有,但不像原来那么频繁了。


同样,老年代对象依旧在涨:



根本问题还没有解决,笔者将继续观察该问题。解决方案查看:JVM的FullGC优化实战(二)

参考链接:

http://blog.csdn.net/kobejayandy/article/details/8496663

http://www.51testing.com/html/78/23978-212519.html

http://blog.csdn.net/rachel_luo/article/details/8992461



还没有评论!
23.20.183.212