目录
heap Space OOM
这种异常经常出现,通常都会出现这个异常,表示内存空间不够,使用如下代码,用一个死循环来生产字符串,由于Java8之后字符串常量池放在堆里面,就会报这个异常
public static void main(String[] args) {
String str = "aaaa";
while (true){
str += str + new Random().nextInt(); //Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
}
}
GC overhead limit OOM
这种情况一般指GC线程运行的时间远大于用户线程的时间,比如说GC占了
98%
的CPU,用户线程只占了2%
设置如下JVM参数会生产这种异常:
- -Xmx10m
- -Xms10m
- -XX:+PrintGCDetails
- -XX:MaxDirectMemorySize=3m
public static void main(String[] args) {
//Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
//超过98%的时间来进行GC并且回收了不到2%的堆内存
int i = 0;
List<String> list = new ArrayList<>();
while (true){
list.add(String.valueOf(++i).intern());
}
}
Direct buffer memory OOM
一般在做
nio异常
的时候会出现
ps: ByteBuffer.allocate(capability) 第一种方式是分配JVM堆内存,属于GC管辖范围,由于需要拷贝所以速度相对较慢。 DirectByteBuffer dires = ByteBuffer.allocateDirect(capability),第二种方式是分配OS本地内存,不属于GC管辖范围,由于不需要内存拷贝所以速度相对较快。
DirectByteBuff 对象作为这块内存的引用进行操作,但如果不断分配本地内存,堆内存很少使用,那么JVM就不需要执行GC,DirectByteBuffer对象们就不会被回收,这时候堆内存充足,但本地内存已经使用光了,再次尝试分配本地内存就会出现OutOfMemoryError,那程序就直接崩溃了。
public static void main(String[] args) {
System.out.println(VM.maxDirectMemory()+" MaxDirectMemory内存");
//一般再做NIO异常的时候会出现
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6 * 1024 * 1024);
//Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
}
UnableToCreateNewNativeThread OOM
导致原因:
1. 你的应用创建了太多线程了,一个应用进程创建太多线程,超过系统承载极限
2. 你的服务器并不允许你的应用程序创建这么多线程,Linux系统默认会允许单个线程可以创建的线程数是1024个
验证代码:
//到Linux主机上运行哈
public static void main(String[] args) {
for (int i = 0;; i++) {
System.out.println("i= "+i);
new Thread( () -> {
System.out.println("i'm creating");
try {
TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
解决方案:
1. 修改服务器配置文件,增加每个线程的进程数
2. 想办法减低应用程序线程的数量
MetaSpace OOM
简单来说,就是元空间的内容太多,元空间的内存不足
设置参数: -XX:MetaSpaceSize=8m -XX:MaxMetaSpaceSize=8m
static class OOMTest{
}
public static void main(final String[] args) {
int i = 0;//模拟计数多少次后发生异常
try {
while (true){
i++;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMTest.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
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);
e.printStackTrace();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/202485.html