内存泄漏与内存溢出

(1)什么叫内存泄漏、内存溢出

内存泄漏:分配出去的内存无法回收,java中的内存泄漏就是给对象分配资源后无法被GC回收
	//例:对象有引用,GC Roots可达,无用
	public class Test {
		Test2  test2 = new Test2();
	}
	public class Test2{
		Test  test = new Test();
	}
内存溢出:程序要求的内存超出了系统所能分配的范围(如:栈满入栈,占空出栈)
	//例:栈满入栈
	public static void main(String[] args) {
		int [] num = new int[5]; 
		for(int count = 0 ;count < 6; count ++){
			num[count] = count;
		}
	}
	//例:栈空出栈
	public static void main(String[] args) {
		int [] num = new int[0]; 
		System.out.println(num[0]);
	}

(2)二者的关系

内存泄漏的堆积最终会导致内存溢出,但从上述例子中可以看出内存泄漏并不是内存溢出的唯一因素

(3)内存泄露的几种场景

1、静态集合类
	如 static HashMap。若容器为静态的,那么它们生命周期与程序一致,
	容器中的对象不管其是否有用在程序结束之前将不能被释放,从而造成内存泄漏
2、未被释放连接
	如数据库连接、IO连接等,如果使用结束之后不关闭其连接会造成大量对象无法回收,从而引发内存泄漏
3、变量不合理的作用域。
	例:下述伪代码中 a对象只在方法fishCount()方法中使用,之后便无用了,但因a为类变量,
	此时a还不能回收,因此造成了内存泄漏
	String a = new String("两条鱼");
	public static void main(String[] args) {
		new Test().fishCount();
		System.out.println("我爱吃鱼");
	}
	
	public void fishCount(){
		System.out.println("我有"+a);
	}
4、内部类持有外部类
	如果一个外部类的实例对象的方法返回了一个内部类的实例对象,
	这个内部类对象被长期引用了(设置为static引用),
	即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,
	这个外部类对象将不会被垃圾回收,造成内存泄露。
	例:
	public class A {
		B b = new B();
		class B{	
		}
		public void setB_C(){
			new C(b);
		}
	}
	public class C{
		private static B cb;
		c(B ab){
			this.cb=ab
		}
	}
5、改变哈希值
	例:
	public class Test {
		int age;
		public void setAge(int age) {
			this.age = age;
		}
		@Override
		public int hashCode() {
			return 1+age;
		}
	}
	public class Test2 {
		public static void main(String[] args) {
			Test test = new Test();
			Set set = new HashSet();
			set.add(test);
			//存入对象后重新修改其hash值
			test.setAge(2);
			//无法找到其对象 返回false 造成内存泄漏
			System.out.println(set.contains(test));
			//无法删除其对象,返回false 造成内存泄漏
			System.out.println(set.remove(test));
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值