内存泄漏查找
    先ps出java的进程号pid

    jstat -gcutil pid 1000
    意思是每1000毫秒查询一次,一直查。gcutil的意思是已使用空间站总空间的百分比。
     
    jstat执行结果

    查询结果表明:这台服务器的新生代Eden区(E,表示Eden)使用了28.30%(最后)的空间,两个Survivor区(S0、S1,表示Survivor0、Survivor1)分别是0和8.93%,老年代(O,表示Old)使用了87.33%。程序运行以来共发生Minor GC(YGC,表示Young GC)101次,总耗时1.961秒,发生Full GC(FGC,表示Full GC)7次,Full GC总耗时3.022秒,总的耗时(GCT,表示GC Time)为4.983秒。
     

    使用“Java内存影像工具:jmap”生成堆转储快照(一般称为headdump或dump文件)。
    jmap命令格式:
    jmap [ option ] vmid
    使用命令如下:
    jmap -histo:live 20954
    jmap -histo:live 20954


    定位到代码

    定位带代码,有很多种方法,比如前面提到的通过MAT查看Histogram即可找出是哪块代码
    Java的内存泄露多半是因为对象存在无效的引用,对象得不到释放,如果发现Java应用程序占用的内存出现了泄露的迹象,那么我们一般采用下面的步骤分析:
    1. 用工具生成java应用程序的heap dump(如jmap)
    2. 使用Java heap分析工具(如MAT),找出内存占用超出预期的嫌疑对象
    3. 根据情况,分析嫌疑对象和其他对象的引用关系。
    4. 分析程序的源代码,找出嫌疑对象数量过多的原因。
     以下一步步的按照项目实例来操作,去解决内存泄露的问题。

    1. 登录linux服务器,获取tomcat的pid,命令:

    [html] view plain copy

        ps -ef|grep java  



    2. 利用jmap初步分析内存映射,命令:

    [html] view plain copy

        jmap -histo:live 3514 | head -7  


    第2行是我们业务系统的对象,通过这个对象的引用可以初步分析出到底是哪里出现了引用未被垃圾回收收集,通知开发人员优化相关代码。


    3. 如果上面一步还无法定位到关键信息,那么需要拿到heap dump,生成离线文件,做进一步分析,命令:

    [html] view plain copy

        jmap -dump:live,format=b,file=heap.hprof 3514  



    4. 拿到heap dump文件,利用eclipse插件MAT来分析heap profile。

    a. 安装MAT插件

    b. 在eclipse里切换到Memory Analysis视图

    c. 用MAT打开heap profile文件。


    Memory Analyzer插件下载

    直接看到下面Action窗口,有4种Action来分析heap profile,介绍其中最常用的2种:

    - Histogram:这个使用的最多,跟上面的jmap -histo 命令类似,只是在MAT里面可以用GUI来展示应用系统各个类产生的实例。


    Shllow Heap排序后发现 Cms_Organization 这个类占用的内存比较多(没有得到及时GC),查看引用:


    分析引用栈,找到无效引用,打开源码:


     https://blog.csdn.net/fishinhouse/article/details/80781673