内存泄露(OOM)现象及举例
一.HeapSize OOM(堆空间内存溢出)
A.eg:List.add(" ")在一个死循环中不断的调用add却没有remove。
B.并发导致。
解决方法有:1.代码提速。这样可以使得相同对象的生存时间更短。更快被GC。
2.I/O操作时候,objecft=null可以辅助GC,一旦方法脱离了作用域,相应的局部变量应用就会被注销。
3.程序跑的飞快,还是出现OOM,考虑到去修改参数配置。
eg:堆的大小,堆空间的大小,堆空间要设置的足够大(相对),如果太大,发生FULL GC会很恐怖
4.内存可能在某些情况增加几十字节空间但未能释放,每次被GC,很老的对象被GC的较慢。
eg:Session中放数据,Session回话消失才会被注销,但是会话要很长的时间才会被注销。
不断的FULLGC就是不抛出OOM的现象,出现这种现象通常是一些藏匿的Bug或配置导致。
eg:Tomcat的session导致,session信息保存在全局的currentHashMap中,大量的HTTPClient访问创建的临时session。
但并保存系统中为之分配的SessionKey中和相关的Cookies信息,导致每次请求都创建session(几十个字节),一般看不出来,是一个堆积如山的过程。
二.PermGen OOM(永久代内存溢出)
A.常量池(JDK1.6,JDK1.7以后常量池不会放在永久代中了。)
string常量对象会在常量池(包含类名,方法名,属性名等信息)中以hash方式存储和访问,hash表默认的大小为1009,当string过多时,可以通过修改-xx:stringtableSize参数来增加Hash元素的个数,减少Hash冲突。
eg:不断的循环调用string中的intern()方法,就会导致OOM.
B.class加载
由于class被卸载的条件十分的苛刻,这个class所对应的classLoader下面所有的class都没有活对象的应用才会被卸载。
解决方法:在每次CGlib动态创建时,都重新给它设置一个classLoader,这样在运行代码就不会出现OOM,会发现大量的class被卸载。
三.DirectBuffer OOM(直接内存内存溢出)
Java中普通I/O用输入/输出流方式实现,输入流InputStream(终端—>直接内存->JVM),输出流(JVM->直接内存->终端),这一过程中有kenel与JVM之间的拷贝(很多次),为了使用直接内存,Java是有一块区域叫DirectBuffer,不是JavaHeap而是cHeap的一部分。
eg:设置-xx:MaxDirectMemorysize:256
分配一个ByteBufferallocateDirect(257*1024*1024)就会导致OOM。
四.StackOverflowError(栈内存溢出错误)
1.StackOverflowError,通常都是程序的问题,JVM对栈帧的大小设置已经很大了。
2.程序运行过程中,方法分派时,会分配frame来存放本地变量,栈,pc寄存器等信息,方法再调用方法会导致Java栈空间无止境的增长(死递归),Java的解决方法是:设置一个私有栈(不在堆内存,而是在NativeMemory),这个栈的空间大小,通过-Xss来设置,数量级在256K-1MB。如果使用空间超过了-Xss限制,就会出现StackOverflowError。
3.eg:死递归
死递归和死循环的区别:死循环类似于while(true)的操作,它的线程栈空间使用不会递增。而死递归需要记录退回的路径,递归过程中调用方法,每个方法运行过程中的本地变量。也就是要记录上下文信息。这些信息会随着内容的增加,占用很大的内存空间。
死递归:
eg:1.组件的复用。
2.子类调用父类(复用父类的方法),父类调用子类(达到多态的效果),这中间要经过许多方法,可能形成环,进而形成死递归。
3.三方框架的问题。
五.其他内存溢出
A.unable to creat new native thread
原因:物理内存不够用或者OS限制了单个进程使用的最大内存,大量的线程分配时,就有可能导致占用的Native Memory很多。
eg:死循环中创建线程并启动,线程内部申请变量,本身不退出。而且设置Os对进程内存的限制。
B.request{} byte for {}out of swap
地址空间不够用(不一定是物理地址,还有swap,显卡,网卡)
C.IoException:too many open files
打开太多的文件,也可能是本地的socket打开太多,而没有被关闭,太多没有关闭套接字导致。
更多精彩内容请看:Java特种兵上册,136-146页的内容。
电子版的下载地址为:http://download.csdn.net/detail/lichunlin1994/7986285