Java虚拟机OOM怎么用
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本文小编为大家详细介绍"Java虚拟机OOM怎么用",内容详细,步骤清晰,细节处理妥当,希望这篇"Java虚拟机OOM怎么用"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。通
千家信息网最后更新 2026年11月02日Java虚拟机OOM怎么用需要注意,为每个线程的栈分配的内存越大,反而越容易产生栈内存溢出异常。
本文小编为大家详细介绍"Java虚拟机OOM怎么用",内容详细,步骤清晰,细节处理妥当,希望这篇"Java虚拟机OOM怎么用"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
通过代码模拟Java虚拟机规范中描述的各个运行时区域内存溢出的场景。
首先,虚拟机启动参数配置如下:
-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 1
输出:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2245) at java.util.Arrays.copyOf(Arrays.java:2219) at java.util.ArrayList.grow(ArrayList.java:213) at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:187) at java.util.ArrayList.add(ArrayList.java:411) at HeapOOM.main(HeapOOM.java:15)Heap def new generation total 9216K, used 8920K [0x32570000, 0x32f70000, 0x32f70000) eden space 8192K, 100% used [0x32570000, 0x32d70000, 0x32d70000) from space 1024K, 71% used [0x32d70000, 0x32e26040, 0x32e70000) to space 1024K, 0% used [0x32e70000, 0x32e70000, 0x32f70000) tenured generation total 10240K, used 5693K [0x32f70000, 0x33970000, 0x33970000) the space 10240K, 55% used [0x32f70000, 0x334ff7f8, 0x334ff800, 0x33970000) compacting perm gen total 12288K, used 135K [0x33970000, 0x34570000, 0x37970000) the space 12288K, 1% used [0x33970000, 0x33991dd8, 0x33991e00, 0x34570000) ro space 10240K, 45% used [0x37970000, 0x37df1888, 0x37df1a00, 0x38370000) rw space 12288K, 54% used [0x38370000, 0x389f04f8, 0x389f0600, 0x38f70000) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
2. 虚拟机栈和本地方法栈溢出
2.1 StackOverflowError
虚拟机抛出StackOverflowError异常,输出:
Exception in thread "main" java.lang.StackOverflowError at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7) at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:8) ... 1 2 3 4
需要注意,为每个线程的栈分配的内存越大,反而越容易产生栈内存溢出异常。
这个不难理解,每个线程分配到栈容量越大,可以建立的线程数量自然就越少,建立线程时就越容易把剩下的内存耗尽。
因此,可以通过"减少内存"的手段来解决栈内存溢出问题。
/** * * * 功能描述: 栈OutOfMemoryError * VM Args:-Xss2M 调大单线程可使用栈空间大小 * @author zhuyiquan90 * @created 2017-9-1 上午11:20:06 * @version 1.0.0 * @date 2017-9-1 上午11:20:06 */ public class JavaVMStackOOM { private void dontStop() { while (true) { } } public void stackLeakByThread() { while (true) { Thread thread = new Thread(new Runnable() { @Override public void run() { dontStop(); } }); thread.start(); } } public static void main(String[] args) { JavaVMStackOOM oom = new JavaVMStackOOM(); oom.stackLeakByThread(); }} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 3. 方法区和运行时常量池溢出
JDK 1.7开始逐步"去永久代化"。在JDK 1.6及之前的版本,由于常量池分配在永久代,可以通过-XX:PermSize和-XX:MaxPermSize限制方法区大小,从而间接限制常量池容量。
import java.util.ArrayList; import java.util.List; /** * * * 功能描述: 运行时常量池内存溢出 * VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M * @author 作者 zhuyiquan90 * @created 2017-9-1 上午11:50:48 * @version 1.0.0 * @date 2017-9-1 上午11:50:48 */ public class RuntimeConstantPoolOOM { public static void main(String[] args) { // 使用List保持常量池引用,避免Full GC回收常量池行为 List list = new ArrayList(); // 10MB的PermSize在integer范围内足够产生OOM int i =0; while(true) { list.add(String.valueOf(i++).intern()); } }} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 在JDK 1.7及以上,while循环将一直进行下去。
方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。对于这些区域的测试,基本的思想是运行时产生大量的类去填满方法去,直到溢出。
package com.suning; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * * * 功能描述: 方法区内存溢出 * VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M * @author 作者 zhuyiquan90 * @created 2017-9-1 下午3:31:27 * @version 1.0.0 * @date 2017-9-1 下午3:31:27 */ public class JavaMethodAreaOOM { public static void main(String[] args) { while (true) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(OOMObject.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // TODO Auto-generated method stub return proxy.invokeSuper(obj, args); } }); enhancer.create(); } } static class OOMObject { }} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 4. 本机直接内存溢出
运行结果:
Exception in thread "main" java.lang.OutOfMemoryError at sun.misc.Unsafe.allocateMemory(Native Method) at DirectMemoryOOM.main(DirectMemoryOOM.java:14) 1 2 3
读到这里,这篇"Java虚拟机OOM怎么用"文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注行业资讯频道。
内存
方法
常量
线程
运行
功能
文章
分配
作者
内容
区域
可以通过
大小
容量
永久
输出
限制
妥当
代码
参数
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
鸠鸠互联网科技
互联网扶贫科技
华宇互联网科技
平安科技 互联网
碳银互联网科技
浩特互联网科技
上海卓越科技 互联网
互联网科技汛
哈尔滨新华互联网科技
蓝色互联网科技
互联网科技中介
特约风豹互联网科技为什么扣费
云南省自由互联网科技有限公司
浙南科技城互联网大厦招聘
工业互联网科技成果转化
35岁以上互联网科技行业
新氧科技和美国互联网有关系吗
全球科技与互联网公司市值变化
互联网科技对化妆品行业
长沙易易互联网科技有限公司
上海挚品互联网科技有限公司
哈尔滨大商圈互联网科技有限公司
华宇互联网科技
银优互联网科技有限公司
国外互联网科技网站
无锡溥仪互联网科技有限公司
保险科技服务互联网营销体系
广州富喜互联网络科技
互联网科技资金流入
前海云享互联网科技