1. 堆溢出

java堆用于存储对象实例,只要不断地创建对象,并且这些对象不会被回收(什么情况对象不会被回收呢?如:由于GC Root到对象之间有可达路径,所以垃圾回收机制不会清除这些对象),那么,当对象的数量达到一定的数量,从而达到了最大堆容量(-Xmx)限制了,这个时候会产生内存溢出异常。

java堆内存溢出异常的堆栈信息“java.lang.OutOfMemoryError:java heap space”

那么如何解决呢?

首先要确认内存中的对象是否是必要的,也就是要区分出现的是内存泄露(Memory Leak)还是内存溢出(Memory Overflow)

如果是内存泄露,要使用工具查看泄露对象到GC Roots的引用链,找到泄露对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收它们。

如果不是内存泄露,那么就要检查JVM参数(-Xmx与-Xms),根据机器物理内存情况看看是否能把参数调大一些,另一方面,从代码层面考虑,看看是否存在某些对象生命周期过长、持有状态时间过长的情况,优化代码,从而尝试减少程序在运行期的内存消耗。

2. 栈溢出

JVM中有虚拟机栈和本地方法栈,栈容量由-Xss参数来设置

在java虚拟机规范中描述两种异常:

1)如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常

2)如果虚拟机在扩展栈时无法申请足够的内存空间,则抛出OutOfMemoryError异常

那么什么时候可能会抛出上面两种异常呢?

a. 一般来说, 在单线程下,无论是由于栈帧太大还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是StackOverflowError异常

b. 程序在不断的创建线程,这可能会产生OutOfMemoryError异常,但是此种情况与栈空间是否足够大并没有任何关系

下面来分析一下情况b

b这种情况,为每个线程的栈分配的内存越大,反而越容易产生内存溢出异常

为什么呢?

原因:操作系统分配给每个进程的内存是有限的(32位Windows限制为2GB),虚拟机提供参数来设置java堆和方法区这两部分内存的最大值,

剩余内存 = 2GB - Xmx(最大堆容量) - MaxPermSize(最大方法区容量)

(程序计数器消耗的内存忽略,因为很小)

那么,可以创建线程的数量可以表示为:

可以创建线程的数量 = 剩余内存 / 线程的容量

所有,若每个线程分配的栈容量(-Xss)越大,可以创建的线程数量就越小

那么,不断的创建线程,把剩余内存逐渐耗尽,当剩余内存不足时,就会抛出OutOfMemoryError异常。

“java.lang.OutOfMemoryError:unable to create new native thread”

如何解决呢?

对于情况a,一般来说是不会出现的,(虚拟机默认参数,栈深度一般情况下可以达到1000-2000没有问题,正常的方法调用,这个深度足够了)

对于情况b,解决办法一个是减少线程数量,若不能减少线程数量,那么考虑“减少内存”的手段来解决,即通过减少最大堆和减少栈容量来换取更多的线程

3. 方法区和运行时常量池溢出

首先,了解一下,在JDK1.6及之前的版本中,常量池分配在永久带内,可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接来限制常量池的大小,

“java.lang.OutOfMemoryError:PermGen space”

JDK1.7开始逐步“去永久代”...,常量池移到了堆中

4. 直接内存溢出

DirectMemory容量默认值与java堆最大值(-Xmx)一样大,也可以通过-XX:MaxDirectMemorySize指定

由DirectMemory导致的内存溢出,可以考虑一下是不是由于程序中使用了NIO导致的,进行排查

哪些情况会导致OOM的更多相关文章

  1. 线上故障排查——drools规则引擎使用不当导致oom

    事件回溯 1.7月26日上午11:34,告警邮件提示:tomcat内存使用率连续多次超过90%: 2.开发人员介入排查问题,11:40定位到存在oom问题,申请运维拉取线上tomcat 内存快照dum ...

  2. Android RecyclerView利用Glide加载大量图片into(Target)导致OOM异常

    学过android的人应该都知道Glide是一个无比强大的图片加载库,它内部已经提供了很好的缓存机制供我们选择,我们只需一个参数调用即可(DiskCacheStrategy()),而不必像Univer ...

  3. Mysql中使用JDBC流式查询避免数据量过大导致OOM

    一.前言 java 中MySQL JDBC 封装了流式查询操作,通过设置几个参数,就可以避免一次返回数据过大导致 OOM. 二.如何使用 2.1 之前查询 public void selectData ...

  4. Android 导致OOM的常见原因

    OOM主要有两种原因导致: 1. 加载大图片: 2. 内存泄漏: 一.加载大图片 在Android应用中加载Bitmap的操作是需要特别小心处理的,因为Bitmap会消耗很多内存.比如,Galaxy ...

  5. 面试官:小伙子,你给我说一下Java中什么情况会导致内存泄漏呢?

    概念 内存泄露:指程序中动态分配内存给一些临时对象,但对象不会被GC回收,它始终占用内存,被分配的对象可达但已无用.即无用对象持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间浪费. 可达 ...

  6. SQL SERVER中什么情况会导致索引查找变成索引扫描

    SQL Server 中什么情况会导致其执行计划从索引查找(Index Seek)变成索引扫描(Index Scan)呢? 下面从几个方面结合上下文具体场景做了下测试.总结.归纳. 1:隐式转换会导致 ...

  7. Java之HashMap在多线程情况下导致死循环的问题

    PS:不得不说Java编程思想这本书是真心强大.. 学习内容: 1.HashMap<K,V>在多线程的情况下出现的死循环现象   当初学Java的时候只是知道HashMap<K,V& ...

  8. 万答#15,都有哪些情况可能导致MGR服务无法启动

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 本文转载自微信公众号 "老叶茶馆" 欢迎大家关注! 1.都有 ...

  9. Thrift反序列化导致OOM(转)

    概述 最近线上的日志处理服务偶尔会出现Out Of Memory的问题,从Exception的call stack中顺藤摸瓜,最终定位到是thrift反序列化的问题. 发现问题 先交代一下问题现场: ...

随机推荐

  1. NLP系列-中文分词(基于统计)

    上文已经介绍了基于词典的中文分词,现在让我们来看一下基于统计的中文分词. 统计分词: 统计分词的主要思想是把每个词看做是由字组成的,如果相连的字在不同文本中出现的次数越多,就证明这段相连的字很有可能就 ...

  2. 教你如何用Docker快速搭建深度学习环境

    本教程搭建集 Tensorflow.Keras.Coffe.PyTorch 等深度学习框架于一身的环境,及jupyter. 本教程使用nvidia-docker启动实例,通过本教程可以从一个全新的Ub ...

  3. Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误)

    Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误) Truffle3.0集成NodeJS并完全跑通(附详细实例,可能的错误) 升级到Truffle3.0 如果之前安装的是Truf ...

  4. redis基础和通用key操作

    redis是什么? redis开源的,构建于内存的数据结构的nosql数据库.常被用于数据存储,缓存处理和消息处理. redis的优势? 1.极高的读写能力 2.丰富的数据类型 3.原子性操作 4.支 ...

  5. Java串口编程学习1-环境配置(64位Win7)

    最近在做zigbee的课程设计,需要Java实现对串口数据的读写操作. 网上找了很多代码,好像都比较过时了,直接拿来用没法跑通……QAQ……然后自己写个教程留底,如有不当之处还请各位路过的大神赐教. ...

  6. PAT 1045 快速排序

    https://pintia.cn/problem-sets/994805260223102976/problems/994805278589960192 著名的快速排序算法里有一个经典的划分过程:我 ...

  7. 写一篇Hook Driver.

    关于Hook,有一本书讲的比较清楚,最近刚刚看完,<Rootkits: Subverting the Windows Kernel> http://www.amazon.com/Rootk ...

  8. Java中break和continue的区别

    continue,继续下一个循环的运算, break,跳出循环

  9. 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组

    题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...

  10. 2017 Multi-University Training Contest - Team 4 phone call(树+lca+并查集)

    题解: (并查集处理往上跳的时候,一定要先让u,v往上跳到并查集的祖先,不然会wa掉) 代码如下: #include <iostream> #include <algorithm&g ...