Java内存溢出和内存泄漏代码示例


看之前可以 看一下这篇文章,有详细解释,本篇文章重在代码示例


A:堆溢出

1.1 温水煮青蛙堆溢出参数

其实就是在堆里面一直放对象,总会有放不下的

1. 堆大小设置成5M
2.参数:
-Xms5m -Xmx5m -XX:PrintGCDetails -verbose:gc
1.2 温水煮青蛙堆溢出代码示例
package neicun;

import java.util.LinkedList;
import java.util.List;

//温水煮青蛙堆溢出 堆溢出实例
public class TestHeap {
   
    public static void main(String[] args) {
        List list =new LinkedList<>();
        int i =0;
        while (true){
            i++;
            if(i%1000 ==0){
                System.out.println("i:"+i);
            }
            list.add(new Object());
        }
    }
}

 
  
1.3 温水煮青蛙,堆溢出异常

  Exception in thread "main" java.lang.OutOfMemoryError:
  GC overhead limit exceeded

2. 巨婴堆溢出

其实就是往一个堆里面扔一个超过堆大小的对象

1. 堆大小设置成5M
2.参数:
-Xms5m -Xmx5m -XX:PrintGCDetails -verbose:gc
public class TestHeap {
   
    public static void main(String[] args) {
		String[] strings =new String[1000000000];

    }
}
2.3 巨婴堆溢出异常
Exception in thread "main" java.lang.OutOfMemoryError:
         Java heap space

B :方法区和常量池溢出

-XX:MaxMetaspaceSize=3M
public class TestHeap {
   
    public static void main(String[] args) {
	List list =new LinkedList<>();

    }
}
 
  
Error occurred during initialization of VM
MaxMetaspaceSize is too small.
就是运行的内存都不够

C:虚拟机栈和本地方法栈溢出

递归有可能产生栈溢出的情况

-Xss256k
默认的是1M
package neicun;

public class TestVmStack {
    private int length =1;

    private void diGui(){
        length++;
        diGui();
    }
    public static void main(String[] args){
        TestVmStack vm =new TestVmStack();

        try {
            vm.diGui();
        }catch (Throwable e){
            System.out.println(vm.length+"========");
            e.printStackTrace();
        }
    }
}

3536========
java.lang.StackOverflowError

内存泄漏

要释放或者要被垃圾回收的的东西,没有被回收

package neicun;

//自定义实现一个栈,但是出栈的时候不把对象删除
public class UserStack {
    private Object[] elements ;
    private  int size =0;//栈顶位置
    private static final int Cap =16;
    public UserStack(){
        elements =new Object[Cap];
    }

    //放入元素
    public void push(Object o){
        elements[size++] =o;
    }
    public Object pop( ){
        Object o =elements[--size];
        return o;
    }

    public static void main(String[] args) {
        UserStack u =new UserStack();
        Object o =new Object();
        System.out.println( o);
        u.push(o);
        Object ret = u.pop();
        System.out.println(ret+" ");
    }
}

java.lang.Object@23fc625e
java.lang.Object@23fc625e 

要想不内存溢出,要把需要被pop出去的元素置空

比如ArrayList的remove源码

      elementData[--size] = null; // clear to let GC do its work 
      这个就是arrayList源码里面的remove方法
 public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

你可能感兴趣的:(Java)