Java-JVM OutOfMemory 情况(JDK8)
JVM 运行时内存结构(Run-Time Data Areas)
内存溢出分为两大类:OutOfMemoryError 和 StackOverflowError。
一、HeapOomError (JVM 堆内存溢出)
-Xms:初始值
-Xmx:最大值
-Xmn:最小值

public static void main(String[] args) {
List<byte[]> list = new ArrayList<>();
int i = 0;
while (true) {
list.add(new byte[8 * 1024 * 1024]);
System.out.println(++i);
}
}

二、MemoryLeakOomError(JVM 堆内存泄漏)
Java 语言中是指,未使用的对象仍然在 JVM 堆空间中存在,任保留着引用,无法被 GC。不停的堆积最终触发堆内存溢出。
三、OverheadLimitOomError(垃圾回收超时内存溢出)
# JDK6 新增错误类型。当 GC 为释放很小空间占用大量时间时抛出。
# (超过 98% 以上的时间去释放小于 2% 的堆空间)
java.lang.OutOfMemoryError: GC overhead limit exceeded # 关闭上述检查功能,通常不治本,最终会 Java heap space。应查看系统是否有使用大内存的代码或死循环
-XX:-UseGCOverheadLimit

static class Key {
Integer id;
Key(Integer id) {
this.id = id;
}
// @Override
// public int hashCode() {
// return id.hashCode();
// }
//
// @Override
// public boolean equals(Object o) {
// boolean response = false;
// if (o instanceof Key) {
// response = (((Key) o).id).equals(this.id);
// }
// return response;
// }
}
public static void main(String[] args) {
Map<Key, String> m = new HashMap<>();
int x = 0;
while (true) {
for (int i = 0; i < 500; i++) {
if (!m.containsKey(new Key(i))) {
m.put(new Key(i), "Number:" + i);
}
}
System.out.println(x++);
}
}

public static void main(String[] args) {
Map map = System.getProperties();
Random r = new Random();
while (true) {
map.put(r.nextInt(), "Oracle Java");
}
}

四、MetaSpaceOomError(Metaspace内存溢出)
元空间的溢出,系统会抛出 java.lang.OutOfMemoryError: Metaspace。出现该错误的原因是类非常多或引用的 jar 包非常多或者通过动态代码生成类加载等方法,导致元空间的内存占用很大。
JDK8 开始,方法区的实现由永久代(PermGen)变成了元空间(Metaspace)。Metaspace 使用的是本地内存,而不是堆内存,也就是说在默认情况下 Metaspace 的大小只与本地内存大小有关。
# 初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整
# 如果释放了大量的空间,就适当降低该值。
# 如果释放了很少的空间,那么在不超过 MaxMetaspaceSize 下适当提高该值。
-XX:MetaspaceSize # 最大空间,默认没有限制。
# 防止因为某些情况导致 Metaspace 无限的使用本地内存,影响到其他程序。应设置大小。
-XX:MaxMetaspaceSize # Metaspace 增长时的最大幅度。
-XX:MaxMetaspaceExpansion # Metaspace 增长时的最小幅度。
-XX:MinMetaspaceExpansion # 当进行过Metaspace GC之后, 会计算当前Metaspace的空闲空间比,如果空闲比大于这个参数,那么虚拟机会释放 Metaspace 的部分空间。在本机该参数的默认值为70,也就是70%。
-XX:MaxMetaspaceFreeRatio # 当进行过Metaspace GC之后,会计算当前 Metaspace 的空闲空间比,如果空闲比小于这个参数,那么虚拟机将增长 Metaspace 的大小。在本机该参数的默认值为40,也就是40%。
# 设置该参数可以控制 Metaspace 的增长的速度,太小的值会导致 Metaspace 增长的缓慢,Metaspace 的使用逐渐趋于饱和,可能会影响之后类的加载。而太大的值会导致 Metaspace 增长的过快,浪费内存。
-XX:MinMetaspaceFreeRatio

public static void main(String[] args) {
ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();
// 借助 CGlib 来动态地生成大量的 Class
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MetaSpaceOomError.class);
enhancer.setCallbackTypes(new Class[]{Dispatcher.class, MethodInterceptor.class});
enhancer.setCallbackFilter(new CallbackFilter() {
@Override
public int accept(Method method) {
return 1;
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
});
Class clazz = enhancer.createClass();
System.out.println(clazz.getName() + "===================================");
// 显示数量信息(共加载过的类型数目,当前还有效的类型数目,已经被卸载的类型数目)
System.out.println("total:" + loadingBean.getTotalLoadedClassCount());
System.out.println("active:" + loadingBean.getLoadedClassCount());
System.out.println("unloaded:" + loadingBean.getUnloadedClassCount());
}
}

五、DirectoryMemoryOomError(直接内存内存溢出)
在使用 ByteBuffer 中的 allocateDirect() 的时候会出现,很多 Java NIO(如 netty)的框架中被封装为其他的方法,出现该问题时会抛出 java.lang.OutOfMemoryError: Direct buffer memory。
如果你在直接或间接使用了 ByteBuffer 中的 allocateDirect 方法,而不做 clear 就会出现类似的问题。
# 堆外内存最大值
-XX:MaxDirectMemorySize

private static int ONE_MB = 1024 * 1024;
private static int index = 0; public static void main(String[] args) {
try {
System.out.println(VM.maxDirectMemory() / ONE_MB);
ByteBuffer.allocateDirect(ONE_MB * 100); // 直接内存操作
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
while (true) {
index++;
// 分配内存
long l = unsafe.allocateMemory(ONE_MB);
// 释放内存
unsafe.freeMemory(l);
}
} catch (Exception | Error e) {
System.out.println("index:" + index);
e.printStackTrace();
}
}

六、StackOomError(栈内存溢出)
当一个线程执行一个Java方法时,JVM将创建一个新的栈帧并且把它push到栈顶。
当一个方法递归调用自己时,每层调用都需要创建一个新的栈帧。当栈中越来越多的内存将随着递归调用而被消耗,最终造成 java.lang.StackOverflowError。
# 每个线程的堆栈大小
-Xss

private static int num = 1;
public void testStack() throws StackOverflowError {
num++;
this.testStack();
}
public static void main(String[] agrs) {
try {
StackOomError t = new StackOomError();
t.testStack();
} catch (StackOverflowError stackOverflowError) {
System.out.println(num);
stackOverflowError.printStackTrace();
}
}

七、ArrayLimitOomError(数组超限内存溢出)
JVM 对应用程序所能分配数组最大大小是有限制的,Java 数组的索引是 int 类型,不同的平台限制有所不同。
在为数组分配内存之前,会执行特定平台的检查:分配的数据结构是否在此平台是可寻址的。
若数组长度超出系统上限就会造成 java.lang.OutOfMemoryError: Requested array size exceeds VM limit。
public static void main(String[] args) {
try {
int[] arr = new int[Integer.MAX_VALUE];
} catch (Throwable t) {
t.printStackTrace();
}
}

https://segmentfault.com/a/1190000017226359
https://blog.csdn.net/bolg_hero/article/details/78189621
Java-JVM OutOfMemory 情况(JDK8)的更多相关文章
- Java JVM虚拟机选项Xms/Xmx/PermSize/MaxPermSize(转)
通过JVM的这些选项:Xms/Xmx/PermSize/MaxPermSize可以牵扯出很多问题,比如性能调优等. 说明:以下转载没经过实践. 经验实例(参考): 设置每个线程的堆栈大小.JDK5.0 ...
- Java JVM【笔记】
Java JVM[笔记] Java的平台无关性是如何实现的? Java源码首先被编译成字节码,再由不同的平台的JVM进行解析,Java语言在不同的平台上运行时不需要进行重新编译,Java虚拟机在执行字 ...
- JAVA JVM虚拟机选项:Xms Xmx PermSize MaxPermSize 区别
Xms : 是指设定程序启动时占用内存大小.一般该值设置大的会使程序启动快,但是可能会使本机暂时变慢. Xmx : 是指设定程序运行期间最大可占用的内存大小,如果程序运行需要占用更多的内存,超出这个 ...
- java JVM垃圾回收机制
Java语言出来之前,大家都在拼命的写C或者C++的程序,而此时存在一个很大的矛盾,C++等语言创建对象要不断的去开辟空间,不用的时候有需要不断的去释放控件,既要写构造函数,又要写析构函数,很多时候都 ...
- Java多线程学习笔记——从Java JVM对多线程数据同步的一些理解
我们知道在多线程编程中,我们很大的一部分内容是为了解决线程间的资源同步问题和线程间共同协作解决问题.线程间的同步,通俗我们理解为僧多粥少,在粥有限情况下,我们怎么去防止大家有秩序的喝到粥,不至于 ...
- Jstatd方式远程监控Linux下 JVM运行情况
前言 最近一个项目部署在服务器上运行时出现了问题,经过排查发现是java内存溢出的问题,所以为了实时监控服务器java内存的情况,需要远程查看服务器上JVM内存的一些情况.另外服务器系统是CentOS ...
- Java JVM 内存泄漏--全解析和处理办法 [ 转载 ]
Java JVM 内存泄露——全解析和处理办法 [转载] @author 小筐子 @address http://www.jianshu.com/p/bf159a9c391a JA ...
- Java OOM 常见情况
Java OOM 常见情况 原文:https://blog.csdn.net/qq_42447950/article/details/81435080 1)什么是OOM? OOM,全称“Out Of ...
- Java JVM技术
.1. java监控工具使用 .1.1. jconsole jconsole是一种集成了上面所有命令功能的可视化工具,可以分析jvm的内存使用情况和线程等信息. 启动jconsole 通 ...
- 【转载】Java JVM : Xms Xmx PermSize MaxPermSize 区别
转载自:http://cxh61207.iteye.com/blog/1160663 java JVM虚拟机选项: Xms Xmx PermSize MaxPermSize 区别 Xms 是指设定程 ...
随机推荐
- boost交叉编译
运行bootstrap.sh # ./bootstrap.sh 生成b2.bjam和project-config.jam文件 修改project-config.jam using gcc : arm ...
- MVP架构的一个小例子
主角: MVP是一种编程的架构模式,M=Model,负责提供数据:V=View,负责显示数据:P=Presenter,负责处理数据. 应用例子: csharp写的一个qq机器人. 一.Model层 获 ...
- 从Windows文件夹到Linux分区
1. 先说几句 如果你, 知道什么是Windows系统 简单使用Windows系统 想要了解或安装Linux 刚接触Linux会有以下疑惑, 什么是分区? 如何建立分区? 怎么安装系统到到D盘? 安装 ...
- Srping事物的隔离策略
spring事务: 什么是事务: 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败. 事务特性(4种): 原子性 (atomicity):强调事务的不可分割. 一致性 (c ...
- 一周死磕fastreport ----ASP.NET (二)
前一章忘了为什么要死磕fastreport 了,这次简单说一下, 公司本来有一个winfrom 窗体打印程序,可是上司觉得太麻烦了,(前几天 我一直在做web版看板,然后发现还不错,于是 想把公 ...
- 简单的jquery进度条插件LineProgressbar.js,myProgress.js
参考 http://www.lanrenzhijia.com/jquery/4121.html demo下载 <script src="js/jquery.lineProgress ...
- Ubuntu打开系统监视器查看进程&资源等信息
Ubuntu打开系统监视器查看进程&资源等信息 类似于Windows的任务管理器,Ubuntu也提供了系统监视器供用户管理进程及查看系统占用资源等 打开方式,终端输入如下命令: gnome-s ...
- Codeforces Round #590 (Div. 3) B2. Social Network (hard version)
链接: https://codeforces.com/contest/1234/problem/B2 题意: The only difference between easy and hard ver ...
- 题解 [51nod1161] Partial Sums
题面 解析 我们设\(f[i]\)表示\(k\)次操作后第一个数在第\(i\)个位置上加了多少次, 而其它的数也可以类推, 第\(i\)个数在第\(j\)个位置加的次数就是\(f[j-i+1]\). ...
- 斑马105SLPlus串口打印二维码
1.根据说明书调试硬件,校准介质还有色带(很重要),我自己搞了好几天才搞明白. 2.设置好参数,比如打印介质连续.非连续,热敏还是热转质 3.打印机上电后悔自动校准,校准成功后就可以直接通过串口打印, ...