内存泄露
含义特点
是指程序在申请内存后,无法释放已申请的内存空间;
通过new的方式开辟一块内存区域,使用完成后,无法释放(被GC回收),导致内存泄露。
发生内存泄露的元素的特点
对象是可达的;对象是无用的(如哈希表中保存的元素但是程序remove失效)
2.1.1 容易出现内存泄露的情况
静态集合类引起内存泄漏
静态变量的生命周期和应用程序一致,静态集合中如果在程序中大量添加元素,而没有正确释放,将导致内存泄露
当集合里面的对象属性被修改后,再调用remove()方法时不起作用
各种连接
数据库连接,网络Socket连接,io连接等如果没有手动关闭close(),则存在泄露的风险
内部类和外部模块的引用
内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。
程序员A 负责A 模块,调用了B 模块的一个方法如: public void registerMsg(Object b);
这种调用就要非常小心了,传入了一个对象,很可能模块B就保持了对该对象的引用,这时候就需要注意模块B 是否提供相应的操作去除引用。
单例模式持有外部对象的引用
单例模式中实例的变量,如果持有外部对象的引用,则外部对象的引用不能被释放。
内存溢出out of memory
含义
内存空间不足,比如要获取一个Long的数据,但系统只能提供了一个int类型的数据空间;内存泄露将会导致内存溢出。
出现的情况
服务器初始内存不足,需加载的文件过多
程序存在死循环或者大量的递归调用
一次产生大量的实体对象,如数据库查询大量数据,大循环中便利产生大量数据
List,Map等集合使用完成后未清空其引用
处理方案
修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
核查代码
Error
OutOfMemoryError:堆区,栈区
OutOfMemoryError:是在程序无法申请到足够的内存的时候抛出的异常
StackOverflowError:栈区
StackOverflowError:是线程申请的栈深度大于虚拟机所允许的深度所抛出的异常。
配置修改
-Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m -Xss1024k
-Xms:分配堆最小内存,默认为物理内存的1/64;
-Xmx:分配最大内存,默认为物理内存的1/4
这个值的比例最好是1:1或者1:1.5。如都为1GB,或者-Xmx和-Xms设为1GB和1.5GB。
-Xss:设置每个线程的堆栈大小。JDK5.0以后每个线程堆 栈大小为1M。
操作系统对一 个进程内的线程数经验值在3000~5000左右。
-XX:PermSize分配非堆最小内存,默认为物理内存的1/64;
-XX:MaxPermSize分配最大内存,默认为物理内存的1/4。