线上定位GC内存泄露问题

原因:Java中存在内存泄露,就是因为对象无用却可达。

举个例子: 
在这个例子中,我们循环申请Object对象,并将所申请的对象放入一个Vector中,如果我们仅仅释放引用本身,那么Vector仍然引用该对象,所以这个对象对GC来说是不可回收的。因此,如果对象加入到Vector后,还必须从Vector中删除,最简单的方法就是将Vector对象设置为null。

Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
    Object o=new Object();
    v.add(o);
    o=null; 
}

//此时,所有的Object对象都没有被释放,因为变量v引用这些对象。 这时候这些Object就是不可用可达的对象,GC不会帮我们清理的, 这就存在了内存泄露了。

//除非你把变量v的每个元素也置空:

Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
    Object o=new Object();
    v.add(o);
    v.get(i) = null;
    o=null;
}

1.ps -ef | grep xxx | grep -v grep:查看进程是否存在。

2.假如1是true的话,则查看tomcat的catlalina.out日志和系统gc日志,是否有内存溢出。

3.假如2是true的话,则用命令:jmap -heap 1000看下java堆的情况。

4.假如2是true的话,则用命令:jstat -gcutil pid 1000和ps -mp 1000 -o THREAD,tid,time>a.log查看堆中各代的占用情况和GC情况。

5.假如3是true的话,则用命令:jstack pid > a.log获取线程Dump信息。

6.假如4是true的话,则用命令:jmap -histo:live和jstat -printcompiliation -h3 1000(注意jmap命令会触发Full GC,并发访问量较大的线上环境慎用)查看了下活对象。

7.假如5是true的话,则打印GC原因:/java/bin/jinfo -flag +PrintGCReason

8.jps -l -m找到处于死锁状态应用的进程id

原文地址:https://www.cnblogs.com/nizuimeiabc1/p/7723538.html