Java内存泄露的原因
1、静态集合类像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放,因为他们也将一直被Vector等应用着。
这种情况可以通过remove clear方式释放对象,没有问题。
2、数据库的连接没有关闭情况,包括连接池方法连接数据库,如果没有关闭ResultSet等也都可能出现内存泄露的问题。
这是代码中经常出现的问题。
3、内部类和外部类的引用容易出现内存泄露的问题;监听器的使用,java中往往会使用到监听器,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。
我认为此说法是不准确, 及时将对象设置为null可以加快内存回收,但并不代表内存不可达或者泄露,我们使用一个例子来验证下
package testawt; import java.io.Console; import java.util.Scanner; import java.util.Vector; class person { public String name; public String age; private hand handhello; public person () { handhello=new hand(this); } public void sayhello() { handhello.Shake(); } public void finalize() { System.out.println("gc person!"); } } class hand { private person per; public hand(person per) { this.per=per; } public void Shake() { System.out.println("Shake!"); } public void finalize() { System.out.println("gc hand!"); } } public class testm { private static Scanner in; public static void main(String[] args) { Vector<person> v = new Vector<person>(); for (int i = 1; i<20; i++) { person o = new person(); v.add(o); } v.clear(); System.gc(); //所有对象释放了 in = new Scanner(System.in); int a = in.nextInt(); for (int i = 0; i < 10; i++) System.out.println(a+i); } }
person和hand存在相互引用。但是强制调用gc ,能够回收内存。
gc person!
gc hand!
gc person!
gc hand!
gc person!
3、大量临时变量的使用,没有及时将对象设置为null也可能导致内存的泄露
我认为此说法不准确,及时将对象设置为null可以加快内存回收,但并不代表内存不可达或者泄露,如果你觉得自己使用了大量的临时变量,可以自己强制执行一次System.gc();
import java.io.Console; import java.util.Scanner; import java.util.Vector; class person { public String name; public String age; public hand handhello; public void finalize() { System.out.println("gc person!"); } } class hand { public void hello() { System.out.println("hello!"); } public void finalize() { System.out.println("gc hand!"); } } class footer { public void walk() { System.out.println("walk!"); } public void finalize() { System.out.println("gc footer !"); } } public class testmain { private static Scanner in; public static void main(String[] args) { // TODO Auto-generated method stub Vector<person> v = new Vector<person>(); for (int i = 1; i<20; i++) { person o = new person(); o.handhello=new hand(); v.add(o); footer f=new footer(); f.walk(); //o = null; } v.clear(); System.gc(); //所有对象释放了 in = new Scanner(System.in); int a = in.nextInt(); for (int i = 0; i < 10; i++) System.out.println(a+i); } }
运行结果
gc footer !
gc hand!
gc person!
gc footer !
gc hand!
gc person!