原因: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