OutOfMemoryError异常 缺乏、安全感 2022-03-12 16:47 157阅读 0赞 # 1.Java堆溢出 # 代码如下: import java.util.ArrayList; import java.util.List; /* * @author zzf * @date 2019年3月6日 下午2:48:03 */ public class HeapOOM { static class OOMObject{} public static void main(String[] args) { List<OOMObject> list=new ArrayList<OOMObject>(); int i=0; while(true){ System.out.println(i++); list.add(new OOMObject()); } } } 设置Java堆大小为20M(通过设置堆最小值-Xms参数与最大值-Xmx参数设置相同防止堆自动扩展),设置参数-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出溢出是Dump当前内存堆转储快照。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70][] -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 1][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 2][] 分析软件下载地址:[http://www.eclipse.org/mat/downloads.php][http_www.eclipse.org_mat_downloads.php] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 3][] ** Java堆内存的OOM异常时常见的内存溢出异常情况,当出现Java堆内存溢出时,异常堆栈信息“java.lang.OutOfMemoryError”会进一步提示“Java heap space”。** ** 解决这个异常主要区分时内存泄漏还是内存溢出。如果是内存泄漏可以看泄漏对象到GC Roots的引用链,最后找到为何垃圾收集器无法自动回收。如果不存在泄漏,这意味着对象都存活,这就检查虚拟机的堆参数(-Xmx和-Xms)。** # 2.虚拟机栈和本地方法栈溢出 # **由于在HotSpot虚拟机中不区分虚拟机栈和本地方法栈,所以对于HotSpot来说-Xoss参数(设置本地方法栈大小)是无效的,栈容量只由参数-Xss参数设定。** 它在Java虚拟机规范中描述了两种异常: * 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。 * 如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。 出现 StackOverflowError的方式: 通过-Xss参数减少栈内存。结果:抛出StackOverflowError异常。 定义大量本地变量,增大方法栈中本地变量表的长度。结果:StackOverflowError异常。 /* * @author zzf * @date 2019年3月6日 下午3:47:21 */ public class JavaVmStackSOF { private int stackLength; public void stackLeak() { stackLength++; // while(1!=2) stackLeak(); } public static void main(String[] args) throws Throwable { JavaVmStackSOF oom = new JavaVmStackSOF(); try { oom.stackLeak(); } catch (Throwable e) { System.out.println(oom.stackLength); throw e; // TODO: handle exception } } } -Xss128k ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 4][] 创建线程导致内存溢出异常: /* * @author zzf * @date 2019年3月6日 下午4:12:15 */ public class JavaVMStackOOM { private void dontStop() { while (true) ; } public void stackLeakByThread() { while (true) { Thread thread = new Thread(new Runnable() { public void run() { dontStop(); } }); thread.start(); } } public static void main(String[] args) throws Throwable { JavaVMStackOOM oom = new JavaVMStackOOM(); oom.stackLeakByThread(); } } **注意这段代码会使系统卡死!!!!!!!亲测** 1.8以后去除了方法区,而元空间在本地内存中所以不受-XX:PermSize和-XX:MaxPermSize的限制。 # 3.元空间内存溢出 # import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /* * @author zzf * @date 2019年3月6日 下午5:23:25 */ public class JavaMethodAreaOOM { static class OOMObject{ } static int i=0; public static void main(String[] args) { while (true) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(OOMObject.class); enhancer.setUseCache(false); System.out.println(i++); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return proxy.invoke(obj, args); } }); enhancer.create(); } } } -XX:MetaspaceSize=1M -XX:MaxMetaspaceSize=100M ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 5][] 元空间大小可以通过-XX:MetaspaceSize=XXM和-XX:MaxMetaspaceSize=XXM设置。 # 4.直接内存溢出 # import java.lang.reflect.Field; /* * @author zzf * @date 2019年3月6日 下午4:45:31 */ public class RuntimeConstantPoolOOM { // -XX:MaxMetaspaceSize=1M -XX:MaxMetaspaceSize=3M public static void main(String[] args) { int i = 0; try { Field field = sun.misc.Unsafe.class.getDeclaredFields()[0]; field.setAccessible(true); sun.misc.Unsafe unsafe = (sun.misc.Unsafe) field.get(null); while (true) { unsafe.allocateMemory(1024 * 1024); i++; } } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("分配次数:" + i); } } } -XX:MaxDirectMemorySize=3M ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 6][] **由DirectMemory导致的内存溢出,其特征就是在Heap Dump文件中不会有明显的异常。** 参考《深入理解Java虚拟机 JVM高级特性与最佳实践》 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70]: /images/20220312/284733f427d6469eb946925e5acc289a.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 1]: /images/20220312/5350b6ba0230457189252fb59177625b.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 2]: /images/20220312/4d65e223c1a8408ea4432c7b66ad40d1.png [http_www.eclipse.org_mat_downloads.php]: http://www.eclipse.org/mat/downloads.php [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 3]: /images/20220312/819a1ed4a203451a96c47e8ab5c39746.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 4]: /images/20220312/d5252d78d698439e979b1061977f7077.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 5]: /images/20220312/1dfa284e9ead4b2394d328012e230eb2.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NTk4MDEx_size_16_color_FFFFFF_t_70 6]: /images/20220312/22ac2f53b9ca4439ae3271d3759bd47f.png
还没有评论,来说两句吧...