1.java.lang.OutOfMemoryError:Java heap space
// -Xms1m -Xmx1m
public static void heapspacetest(){
String str="helloworld";
while (true){
str+=str+new Random().nextInt(11111111)+
new Random().nextInt(11111111);
}
}
2.java.lang.OutOfMemoryError:GC overhead limit exceeded 超过GC开销限制
package com.yuan1.day1;
import java.util.ArrayList;
import java.util.List;
/**
* @author QLBF
* @version 1.0
* @date 2021/6/17 19:18
*/
/*
* 一开始先设置-Xmx10m
* */
public class test14 {
public static void main(String[] args) {
int i=0;
List<String> list=new ArrayList<>();
try {
for (int j = 0; j < 260000; j++) {
list.add(String.valueOf(j).intern());
i++;
}
} catch (Throwable e) {
e.printStackTrace();
}finally {
System.out.println("i=>"+i);
}
}
}
再设置-Xmx10m -XX:-UseGCOverheadLimit,就可以验证字符串常量池在jdk1.8之后放在了堆中:
package com.yuan1.day1;
import java.util.ArrayList;
import java.util.List;
/**
* @author QLBF
* @version 1.0
* @date 2021/6/17 19:18
*/
/*
* 再设置-Xmx10m -XX:-UseGCOverheadLimit
* */
public class test14 {
public static void main(String[] args) {
int i=0;
List<String> list=new ArrayList<>();
try {
for (int j = 0; j < 260000; j++) {
list.add(String.valueOf(j).intern());
i++;
}
} catch (Throwable e) {
e.printStackTrace();
}finally {
System.out.println("i=>"+i);
}
}
}
3.java.lang.OutOfMemoryError:Direct buffer memory 直接缓冲存储(与NIO有关)
// -Xms10m -Xmx10m -XX:MaxDirectMemorySize=5m -XX:+PrintGCDetails
//此参数的含义是当Direct ByteBuffer分配的堆外内存到达指定大小后,即触发Full GC。
public static void directbuffermemoneytest() throws InterruptedException {
System.out.println("配置分配的MaxDirectMemorySize:"+
(sun.misc.VM.maxDirectMemory()/(double)1014/1024)+"MB");
TimeUnit.SECONDS.sleep(2);
// -Xms10m -Xmx10m -XX:MaxDirectMemorySize=5m -XX:+PrintGCDetails
// 我们配置的5M,但是实际使用的6M,故意搞破坏
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6 * 1024 * 1024);
}
上面那个不太清晰,看黑马的这个:
package com.yuan1.day1;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* @author QLBF
* @version 1.0
* @date 2021/6/17 20:30
*/
public class test15 {
static int _100Mb = 1024 * 1024 * 100;
public static void main(String[] args) {
List<ByteBuffer> list=new ArrayList<>();
int i=0;
try {
while (true){
ByteBuffer byteBuffer=ByteBuffer.allocateDirect(_100Mb);
list.add(byteBuffer);
i++;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(i);
}
}
}
4.java.lang.OutOfMemoryError:unable to create new native thread 无法创建新的本地线程
比如newCachedThreadPool会出现,因为最大线程数是integer的max
//在 Linux 虚拟机下操作,使用非 root 用户测试,因为root用户是无上限创建线程的。
public static void newthreadwuxian(){
for (int i = 0; ; i++) {
System.out.println("i=>"+i);
new Thread(()->{
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
},""+i).start();
}
}
5.java.lang.OutOfMemoryError:Metaspace
简单演示:
package com.yuan1.day1;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* 演示元空间内存溢出 java.lang.OutOfMemoryError: Metaspace
* -XX:MaxMetaspaceSize=8m
*/
public class Demo1_8 extends ClassLoader { // 可以用来加载类的二进制字节码
public static void main(String[] args) {
int j = 0;
try {
Demo1_8 test = new Demo1_8();
for (int i = 0; i < 10000; i++, j++) {
// ClassWriter 作用是生成类的二进制字节码
ClassWriter cw = new ClassWriter(0);
// 版本号, public, 类名, 包名, 父类, 接口
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);
// 返回 byte[]
byte[] code = cw.toByteArray();
// 执行了类的加载
test.defineClass("Class" + i, code, 0, code.length); // Class 对象
}
} finally {
System.out.println(j);
}
}
}
实际开发中由于maybatis使用cglib动态代理生成字节码文件,加载非常多,就很容易方法区oom,eg:
package com.yuan;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author QLBF
* @version 1.0
* @date 2021/5/28 11:18
*/
// 注意要导入 spring 的核心包!
// -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
public class Test {
static class OOMtest{
public static void main(String[] args) {
int i = 0; //模拟计数器,来查看多少次以后发生异常
try {
while (true){
i++;
// Spring的cglib动态代理技术
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(OOMtest.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return method.invoke(o,args);
}
});
enhancer.create();
}
} catch (Throwable e) {
System.out.println("i=>"+i);
e.printStackTrace();
}
}
}
}
参考:狂神