java.lang.StackOverflowError
demo
栈的深度方法调用导致的堆栈溢出
package com.interview.demo.oom;
/**
* @Author leijs
* @date 2022/3/30
*/
public class StackOverflowErrorDemo {
public static void main(String[] args) {
stackOverflowError();
}
private static void stackOverflowError() {
stackOverflowError();
}
}
堆栈溢出属于Error
java.lang.OutOfMemory: java heap space
demo
内存只调整1M
import java.util.Random;
/**
* @Author leijs
* @date 2022/3/30
*/
public class JavaHeapspaceDemo {
public static void main(String[] args) {
String str = "youzan";
while (true) {
str += new Random().nextInt(111111111) + new Random().nextInt(222222222);
}
}
}
堆内存溢出属于Error
java.lang.OutOfMemory: GC overhead limit exceeded
GC回收过长时会抛出OutOfMemoryError. 过长的定义是,98%的时间用来做GC并且回收了不到2%的堆内存。连续多次GC都只回收了不到2%的极端情况下才会出现。假如不抛出GC overhead limit 错误会发生什么情况呢?那就是GC清理的这么点内存会很快再次填满,迫使GC再次执行,这样就形成了恶性循环。CPU使用率一直是100%,而GC没有任何效果。
demo
package com.interview.demo.oom;
import com.google.common.collect.Lists;
import java.util.List;
/**
* @Author leijs
* @date 2022/3/30
*/
public class GCOverheadDemo {
public static void main(String[] args) {
int i = 0;
List<String> list = Lists.newArrayList();
while (true) {
list.add(String.valueOf(++i).intern());
}
}
}
java.lang.OutOfMemory: Direct buffer memory
出现原因:
demo
package com.interview.demo.oom;
import sun.misc.VM;
import java.nio.ByteBuffer;
/**
* @Author leijs
* @date 2022/3/30
*/
public class DirectBufferMemoryDemo {
public static void main(String[] args) {
System.out.println("配置的maxDirectMemory:" + VM.maxDirectMemory() / 1024 / 2024 + "MB");
// 分配OS本地内存,不属于GC管辖范围
ByteBuffer bb = ByteBuffer.allocateDirect(6 * 1024 * 1024);
}
}
java.lang.OutOfMemory: unable to create new native thread
导致原因
准确的将native thread异常与对应的平台有关。
- 应用创建了太多的线程,超过系统承载极限
服务器不允许你的应用创建这么多的线程,linux默认允许单个进程可以创建的线程数是1024个;应用创建超过这个数量,就会报错这个
解决办法
降低线程创建的数量,分析应用是否需要创建这么多的线程
- 确实需要,可以修改linux服务器的限制,扩大linux的默认限制
demo
```java package com.interview.demo.oom;
import java.util.concurrent.TimeUnit;
/**
- @Author leijs
- @date 2022/3/30
*/
public class UnableCreateNewThreadDemo {
public static void main(String[] args) {
} }for (int i = 0; ; i++) {
System.out.println("==============" + i);
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}

<a name="TlAD6"></a>
### linux调整最大线程数
非Root用户:ulimit -u <br />1024
修改: vim /etc/security/limits.d/90-nproc.conf
<a name="kABQc"></a>
## java.lang.OutOfMemory: Metaspace
-XX:+PrintFlagsInitial 默认20多MB<br />元空间使用的是本地内存,主要存放:
- 虚拟机加载的类信息
- 常量池
- 静态变量
- 即时编译后的代码
<a name="bb5eP"></a>
### demo
```java
package com.interview.demo.oom;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @Author leijs
* @date 2022/3/30
*/
public class MetaspaceOOMDemo {
public static void main(String[] args) {
// 计数多少次发生异常
int i = 0;
try {
while (true) {
i++;
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 methodProxy.invokeSuper(o, args);
}
});
enhancer.create();
}
} catch (Exception e) {
System.out.println("多少次异常:" + i);
throw e;
}
}
static class OOMTest {
}
}