1.java的内存泄漏,指一个不再被程序使用的对象或变量一直占据在内存中,并且不能被GC回收(该释放的对象没有被释放)。
常见情况:(1)各种连接并没有调用关闭方法(例如数据库的连接),使用监听器,释放对象时,忘记删除监听器。
(2)长生命周期对象持有短生命周期的引用。例如:
public class Test(){
Object object;
public void method(){
object=new Object();
}
}
object容易产生内存泄漏,调用method方法,不能释放object对象,解决方法一:将object当做局部对象,放入method方法中。解决方法二:在method方法中,最后一行加入如下代码:object=null;
(3)静态集合类的引用(HashMap、Vector的引用)
static Vector v=new Vector(5);
for(int i=0;i<5;i++){
Object object=new Object();
v.add(object);
object=null;
}
静态成员变量v的存在周期跟程序运行时间一致,object不能被释放,因为它一直被vector引用着,仅仅释放Object也无用(object=null),因为一直调用v.add(object),GC机制不能回收。简单的处理方法是将vector对象赋值为null.
(4)非静态内部类持有外部类(Android)
如果一个外部类的实例对象返回一个内部类的实例对象,那么这个内部类将一直被引用,外部类得不到释放,不会被GC回收,造成内存泄漏。
(5)改变哈希值
当一个对象存储进HashSet中,就不能修改参与计算的hash字段了,如果修改掉以后,就与最初存储的值不一样,当使用参数寻找对象时,便找不到该对象,造成内存泄漏。
(6)单例模型
单例对象在初始化后将在JVM整个生命周期中存在,如果单例对象持有外部类的引用,这个对象不会被GC回收,造成内存泄漏。
2.java内存分配
java程序运行时分为静态区(方法区)、栈区、堆区。
静态区:主要存放静态数据、常量,在程序编译时就已经分配好。
栈区:方法都是在栈区运行,方法运行时,局部变量在栈区建立,方法结束时,会自动释放局部变量,栈区的运行效率极高,但是内存有限。
堆区:实例化对象,存储new出来的对象,由GC回收。
来源:CSDN
作者:沐之。
链接:https://blog.csdn.net/qq_35449051/article/details/104101757