版权声明:本文为HCG原创文章,未经博主允许不得转载。请联系[email protected] https://blog.csdn.net/qq_39455116/article/details/86743045
看之前可以 看一下这篇文章,有详细解释,本篇文章重在代码示例
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<Object> 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<Object> 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;
}