1、首先得搞清楚什么叫内存泄露,简单来说就是一个东西放在内存里的时间太长了,当你的程序都跑完了,它还存在那里。这时它是白白的占用了你的内存,累积起来占用的内存越来越多……最后就会导致JVM报错:out of memory。
2、一般情况下,别人如果能指出你的系统(程序)内存溢出,这个人应该还是挺厉害的。通常对于新人来说,喜欢把变量直接定义在class下(此时称之为实例变量,或者成员变量),那么在方法里调用后,这个实例变量是不会被释放的,大量的这样使用就可能会引发内存泄露。
3、把变量定义在方法里,当这个方法执行完毕后内存就得到释放了,这是个好习惯。
4、如果想要看到内存溢出,可以按这样的思路去尝试一下:定义一个静态的实例变量(list或其它集合),然后在一个方法里循环往这个静态变量塞东西,直到这个实例变量撑爆你的jvm内存。很快你就能看到out of memory……
import java.util.ArrayList;
import java.util.List;
public class MemoryTest {
private static List list = new ArrayList();
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
System.out.println("申请前的可用内存 = "+getFreeMemory());
while(true){
list.add(new byte[1024*1024]);//用实例变量申请1M内存,当方法执行完毕时,这个static的变量是不会被释放
count++;
if (count % 100 == 0) {
System.out.println("当前list.size()="+list.size()+",可用内存 = "+getFreeMemory());
Thread.sleep(500);
}
}
}
public static long getFreeMemory() {
return Runtime.getRuntime().freeMemory() / (1024 * 1024);
}
}
其实Java中不可能存在内存泄漏,因为GC会在必要的时候回收内存。
这个例子没有体现内存泄漏,但是用来理解内存泄漏的潜在发生可能还是可以的。
不需要那么复杂,一个非常简单的例子就能说明问题:
Object o1 = new Object();
Object o2 = o1;
o1 = null; // 这时o1指向的那个对象回收了吗?没有,因为它还被o2引用着
o2 = null; // 这样才能回收
实际应用中,只要o2的作用域很小,不执行o2=null也是没有问题的,因为只要o2过了它的生存期,它指向的对象就能被回收。
结论是,作用域越大的变量,越要引起重视,因为它可能占用着某些对象引用而导致对象不能被回收。换句话说,尽可能地缩小变量的作用域——这也是你在Java中关于内存方面能做的唯一努力了。---引用别人的
public Test{
public void test(){
while(true){
this.test();
}
}
public static void main(String[] args) {
new Test().test();
}
}
使用递归
1、首先得搞清楚什么叫内存泄露,简单来说就是一个东西放在内存里的时间太长了,当你的程序都跑完了,它还存在那里。这时它是白白的占用了你的内存,累积起来占用的内存越来越多……最后就会导致JVM报错:out of memory。
2、一般情况下,别人如果能指出你的系统(程序)内存溢出,这个人应该还是挺厉害的。通常对于新人来说,喜欢把变量直接定义在class下(此时称之为实例变量,或者成员变量),那么在方法里调用后,这个实例变量是不会被释放的,大量的这样使用就可能会引发内存泄露。
3、把变量定义在方法里,当这个方法执行完毕后内存就得到释放了,这是个好习惯。
4、如果想要看到内存溢出,可以按这样的思路去尝试一下:定义一个静态的实例变量(list或其它集合),然后在一个方法里循环往这个静态变量塞东西,直到这个实例变量撑爆你的jvm内存。很快你就能看到out of memory……
import java.util.ArrayList;
import java.util.List;
public class MemoryTest {
private static List list = new ArrayList();
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
System.out.println("申请前的可用内存 = "+getFreeMemory());
while(true){
list.add(new byte[1024*1024]);//用实例变量申请1M内存,当方法执行完毕时,这个static的变量是不会被释放
count++;
if (count % 100 == 0) {
System.out.println("当前list.size()="+list.size()+",可用内存 = "+getFreeMemory());
Thread.sleep(500);
}
}
}
public static long getFreeMemory() {
return Runtime.getRuntime().freeMemory() / (1024 * 1024);
}
}