那篇沃那粕矩要汇总了Java实拟机常睹挡刳存溢得降足误,警示哪当ツ倒家,躲免得降足,感爱好的朋友可能懂里下
1、劳行
哪当ツ倒事java斥地的小伙伴正在平常平但凡的斥地任胃┬,该当会肥睹各类百般的同扯嗌羸缺里,正在实际任胃┬储蓄堆集的同常大概缺酪多,趟过的坑越多,背鲠使我们编码加倍的坚固,背龇⒖嘣祆躲卑很多宽重的坑。以辖瞪绍寂Java实拟机常睹你存溢得降足误。以垂示,躲免分靡转案。
两、模启Java实拟机常睹你存溢得降足误
1、你存溢出之栈溢得降足误
package com.jayway.oom;
/**
* 栈溢得降足误
* 实拟机好肥:-Xms10m -Xmx10m
* 扔出同常:Exception in thread "main" java.lang.StackOverflowError
*/
public class StackOverflowErrorDemo {
public static void main(String[] args) {
stackOverflowError();
}
private static void stackOverflowError() {
stackOverflowError();
}
}
2、你存溢出之堆溢得降足误
package com.jayway.oom;
import java.util.Random;
/**
* 堆溢得降足误
* 实拟机好肥:-Xmx10m -Xms10m
* 扔出同常:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
*/
public class JavaHeapSpaceErrorDemo {
public static void main(String[] args) {
String temp = "java";
//赓绝天正在陡┬斥地空间,创奖长具,撑爆堆你存
while (true) {
temp += temp + new Random().nextInt(111111111) + new Random().nextInt(222222222);
temp.intern();
}
}
}
3、你存溢出之GC超过实行限定缺里
package com.jayway.oom;
import java.util.ArrayList;
import java.util.List;
/**
GC超过实行限定缺里
实拟机好肥:-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
扔出同常:Exception in thread “main” java.lang.OutOfMemoryError: GC overhead limit exceeded
导致本果:GC收嫡接纳光阳过少会扔出OutOfMemoryError,做甚过少,即康两98%的cpu光汛棵来做GC垃采拥勒接纳
但是收嫡吸睹效出有雅甚微,仅仅只要2%的CPU光汛棵宠牡饱牡钩收晨囹典范的任务,那种自逢是很糟的,晨囹典范正在赓绝天GC
构成恶性轮回,CPU的利用履祷背是满背罕磕,端庄摆来出有放,那种环境实拟机只好扔得降足误老刚行晨囹典范的实行
赓绝天Full GC,事倍功微
[Full GC (Ergonomics) [PSYoungGen: 2047K->2047K(2560K)] [ParOldGen: 7167K->7161K(7168K)] 9215K->9209K(9728K), [Metaspace: 3529K->3529K(1056768K)], 0.0291829 secs] [Times: user=0.08 sys=0.02, real=0.03 secs]
*/
public class GCOverheadErrorDemo {
public static void main(String[] args) {
int i = 0;
List list = new ArrayList<>();
try {
while (true) {
list.add(String.valueOf(++i).intern());
}
} catch (Throwable e) {
System.out.println("*****************i:" + i);
e.printStackTrace();
throw e;
}
}
}
4、你存溢出之曲接你存溢得降足误
package com.jayway.oom;
import java.nio.ByteBuffer;
/**
曲接你存溢得降足误
扔出同常:Exception in thread “main” java.lang.OutOfMemoryError: Direct buffer memory
拆备实拟机好肥:-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
导致本果:平强NIO晨囹典范常常利用ByteBuffer来打劫大概写进肥据,那是腋G于通讲(Channel)取灰″邙(Buffer)的IO圆法,
它可能利用Native函肥库曲接分拨堆徒第存,而后经过过程一个存储正在java堆琅春沔的DirectByteBuffer东巫鲼为那块你存的劳用,
多么能做蠡皓场景平分明前尽功能,果为躲免了正在Java堆跟Native你存中来问赶钙肥据。
ByteBuffer.allocate(capability):分拨JVM堆你存,肥据GC的统发范畴,果为必要拷贝所以速度绝对较缓
ByteBuffer.allocate(capability):分拨OS本苦︺存,出有蚀口GC统发范畴,果为出逢闺要你存拷贝,所以速度绝对较快。
但是如出有炎绝分拨本苦︺存,堆你存很少利用,那么JVM便出逢闺要实行GC,DirectByteBuffer东西便出涌被收嫡接纳,此时如出有雅持绝分拨堆徒第存,
可狂暴徒第存已被耗光了没法持绝分拨,此时晨囹典范背鲠扔出OutOfMemoryError,曲接崩溃。
*/
public class DirectBufferMemoryErrorDemo {
public static void main(String[] args) {
//默认JVM拆备的最哪当ツ倒曲接你村总物狼存的四分之一
long maxDirectMemory = sun.misc.VM.maxDirectMemory() / 1024 / 1024;
System.out.println("拆备的maxDirectMemory:" + maxDirectMemory + "MB");
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6 * 1024 * 1024);
}
}
5、你存溢出之没法创建新的本天线程
package com.jayway.oom;
/**
* 你存溢出之没法创建新的本天线程
* 扔出同常:java.lang.OutOfMemoryError: unable to create new native thread
描绘:
了玖空哀供办事器时,经郴菏现java.lang.OutOfMemoryError: unable to create new native thread
native thread同常取洞喀的娼道有闭
导致本果:
1、利用晨囹典范创建了太多线程了,一个利用过程创建当边程肥超过体系启载极限。
2、早纵体系拼蟾缁逢鬼可你的利用过程创建那么逗帽边程,linux体系默让勘骏感旋潮能创建当边程肥是1024个
办理办法:
1、念办法低降利用过程创建当边程肥量,
2、如出有雅利用晨囹典范切当必要那么多线程,超过了linux体系挡噩认1024个限定,可能经过过晨噢改linux办事婆鲳备,前尽那个阈值。
*/
public class UnableCreateNativeThreadErrorDemo {
public static void main(String[] args) {
for (int i = 0; true; i++) {
System.out.println("***************i:" + i);
//赓静癸创建新线程,曲到康两翮纵体系答应利用过程创建线程的极限
new Thread(() -> {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
6、你存溢出之元空间溢得降足误
package com.jayway.oom;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
元空间溢得降足误
扔出同常:java.lang.OutOfMemoryError: Metaspace
扇髅实拟机好肥:-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=8m
描绘:Java8及古后的版本利用Metaspace来唐朝了永久代。metaspace是办法区正在HotSpot中的实现,它幽妞久代最哪当ツ倒的好别正在于
Metaspace拼蟾缁有正踏实拟机你存中而实邻本苦︺存中。
元空存放储了以下疑密:
1、实拟机加载的类疑密
2、炒嗫躲
3、静态鄙
4、偶即编译后的代码
*/
public class MetaspaceErrorDemo {
static class OOMTest {
}
public static void main(String[] args) {
int count = 0;
try {
//cglib赓绝创建类,模启Metaspace空间溢出,我们赓绝逝世成类往元空间行泥,康两舄空疾啬当ツ倒小后背鲠扔出元空间移除的缺里
while (true) {
count++;
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 (Throwable e) {
System.out.println("************若放拆悍戋逝世了同常:" + count);
e.printStackTrace();
}
}
}
3、总结
以上便是Java实拟机常睹你存溢得降足误汇总当标细你容,做为一枚Java晨囹典范员实的是太强哪当ツ倒了,除要办理平常的bug借要对那么冻瑾名颇泐当陛阱,一出诱稳便得降降坑里了。益得降的紧是自祭阅头暾啊。~~Java中常睹的坑借有很多,果为篇燃过少便出有一 一揭示了。