Memory leak reason

1. 高内存使用

现在的生产环境都是10,20GB以上的内存,而代码方面的不严谨不修改,盲目的增加内存,加大heap,会导致当系统在大内存下进行gc时的STW的时间变长,这是最常见的高内存使用问题

2. HTTP session 当做cache

因为http session的易用性,很多开发把太多的object存放在HTTP session中,导致session越来越大(每个用户一个),而且session的销毁一般都是30分钟以上(为了保证用户使用性),导致内存中的session非常庞大而且释放不了(高负载,高并发情况下)

同时,OSIV的技术手段会把hibernate session也放在HTTP session中(更大了)

memory leak不知不觉就发生了

更别说,还有session replication等技术手段,更慢更容易出错

3. 错误的cache使用

在cache中存放过多的东西,导致memory leak, 这里说的更多的是tomcat 本地缓存

过多的缓存,导致GC

有的缓存的实现,使用了soft reference,将会在GC的时候清除,缓存过多导致GC频繁(只有在GC之后剩余空间不足的情况下,才会GC 软引用),这种缓存引起的错误很难被发现,会被错误的看成eden空间不足等

4. 高事物内存

如果每个事物的内存使用很高,会导致Young代很快达到Minor GC标准,如果是高并发情况下大量事物内存,导致Young满了,然后Minor GC频发,然而那些事物内存对象又没有die,所以几次之后就被移到了Old中,问题很快潜伏下来,知道最后爆发,而且光靠OutofMemory Error发生那一刻的heap,可能看不出这个问题的存在,只有full heap dump才可能

5. 太大的临时对象

比如XML文件解析等,一次性读取了太大的对象

6. ClassLoader问题

Class load在Perm中,一般都是比较稳定的大小,一旦Perm满了,class再要load没有空间就报OutOfMemory Error错误了

发生这类问题的原因可能有:

6.1 太多的类,类有太多的方法,类变量等,这种问题一般在应用启动的时候就抛错了

6.2 同一个类在jvm中存在多个,发生这种情况的原因主要是因为jvm中因为不同的classcloader加载同一个类,使一个类存在多份,同样的jar包,可能因为此原因被多次加载

6.3 同一个class被重复的加载,在某些情况下,一个class只被使用一点时间,那么方法区的classes信息也是会被GC的,不同的JVM,HotSpot只会在FULL GC的时候做,而IBM和JRockit则每次GC都会,那么这个class就会成为问题,不同的被load,GC,load,GC....

7错误的hashcode和equals方法

当实现错误的hashcode和equals方法后,对象可能会被不断添加到map中,导致内存爆表,而且这种问题很难通过heap dump发现,最好通过代码检查工具来做

 

原文:

http://apmblog.compuware.com/2011/12/15/the-top-java-memory-problems-part-2/

 

 

你可能感兴趣的:(memory leak)