1、什么是内存泄露java
内存泄露是指一个不在被程序使用的对象或变量还在内存中占有存储空间。数据库
1. 内存泄露主要有两种状况:网络
(1). 在堆中申请的空间没有释放工具
(2.) 该对象已经再也不使用,却还在内存中保留着this
通常垃圾回收机制能够有效的解决第一种状况。spa
Java内存泄露主要是第二种状况。线程
1 Vector v = new Vector(); 2 for ( int i=0 ;i<10; i++ ){ 3 Object o = new Object(); 4 v.add(o); 5 }
在循环中不断建立对象加入到Vector对象中,退出循环后o的做用域将会结束,日志
在v中使用这些对象,垃圾回收器没法回收,形成内存泄露。只有将这些对象从code
vector中删除才能释放这些对象。对象
2. 泄露缘由
(1)静态集合类。例如 HashMap 和 Vector 。若是这些容器为静态的static,他们
的生命周期和程序一致,那么容器中的对象在程序结束以前不能被释放,从而形成
内存泄露。也就是长生命周期对象持有短生命周期的对象。
(2)各类链接。如数据库链接、IO链接、网络链接等。须要先创建链接,不使用时
要使用 close() 释放链接,只有关闭链接后垃圾回收器才会回收对应的对象,不然会
有大量对象没法回收二形成内存泄露。
(3)监听器。一般一个应用中用到多个监听器,当释放对象时,每每没有删除相应
的监听器,而形成内存泄露。
(4)变量做用域不合理。若是一个变量的做用域大于其使用的范围,可能会形成内
存泄露。如:
1 Class Server{ 2 private String msg; 3 public void receiveMsg(){ 4 readFromNet();//从网络中接收msg 5 saveDB();//保存msg到数据库 6 } 7 }
从网络中接收msg而后保存到数据库以后msg就没用了,可是msg生命周期和对象的
生命周期相同,因此不会马上被回收,形成内存泄露。
(5)单例模式可能会形成内存泄露。
1 public class BigClass{ 2 //code 3 } 4 public class Singleton { 5 private Singleton(BigClass bc){ 6 this.bc = bc; 7 } 8 private BigClass bc; 9 private static Singleton instance = new Singleton(new BigClass()); 10 public Singleton getInstance(){ 11 return instance; 12 } 13 }
单例模式Singleton存在一个对对象 bc 的引用,可是单例instance对象以静态方式存储,它
在JVM整个生命周期都存在,bc没法被回收,致使内存泄露。
3. 内存泄露的解决方案:
(1)避免在循环中建立对象
(2)最先释放无用对象
(3)尽可能少用静态变量,由于静态变量在永久代,不多参加垃圾回收。
(4)使用字符串处理避免使用String,而用StringBuffer。
4.如何查找内存泄露
使用Jconsole。
2、什么是内存溢出
指的是程序运行过程当中没法申请到足够的内存空间而致使的一种错误。
1. 内存溢出的几种状况:
除了程序计数器外,虚拟机其余几个运行时区域均可能发生OutOfMemorryError(OOM)异常。
(1)虚拟机栈和本地方法栈溢出
若是线程请求的栈深度大于虚拟机所容许的最大深度, 将抛出
StackOverflowError 异常。
若是虚拟机在扩展栈时没法申请到足够的内存空间, 则抛出
OutOfMemoryError 异常。
(2)堆溢出
通常的异常信息:java.lang.OutOfMemoryError:Java heap spaces。
检查虚拟机的参数(-Xmx 与-Xms)的设置是否适当。
(3)方法区溢出
异常信息:java.lang.OutOfMemoryError:PermGen space。
(4)运行时常量池溢出
异常信息:java.lang.OutOfMemoryError:PermGen space。
若是要向运行时常量池中添加内容, 最简单的作法就是使用
String.intern()这个Native 方法。该方法的做用是:若是池中已经包含一个
等于此String 的字符串,则返回表明池中这个字符串的String 对象;不然,
将此String 对象包含的字符串添加到常量池中,而且返回此String 对象的引
用。
2. 内存溢出的缘由
(1)内存中加载的数据过于庞大,如一次从数据库取出过多数据
(2)集合类中对对象的引用,使用完未清除,JVM没法回收
(3)代码中存在死循环或循环产生过多重复的对象实体
(4)启动参数内存值设置太小
3.内存溢出解决办法
(1)修改JVM启动参数,直接增长内存
通常要将-Xms 和-Xmx 选项设置为相同,以免在每次GC 后调整堆的大小;建
议堆的最大值设置为可用内存的最大值的80%
(2)检查错误日志,查看 “outOfMemory” 错误前是否有其余异常或错误
(3)使用内存查看工具动态查看内存使用状况(Jconsole)。
扩展:基本上若是抛出OutOfMemory 有两种缘由:1.内存泄露。2.应用程序自己就是须要这么多的内存。