常见的OOM是以下这几种:

1.GC overhead limit exceeded

2.Java Heap Space

3.Unable to create new native thread

4.PermGen Space

5.Direct buffer memory

6.request {} bytes for {}. Out of swap space?

一直自认为不会有超过这个范围的OOM类型出现,没想到最近看到了一个新的OOM的类型,而这次OOM引发了一次严重的故障,整个排查过程是内部一个同事排查的,文章也是他写的,感谢他的文章,让我也学习到了之前遗漏的一个OOM相关的知识点。

故障现象为

应用日志中发现了大量的OOM异常:

Caused by: java.lang.OutOfMemoryError: Map failed

跟踪堆栈找到抛出异常的地方是在 FileChannle#map,这个方法是创建一个内存映射文件,应用为了降低堆内存的使用,同时提高写入的效率,将一个文件分成多段,内存映射多个MappedByteBuffer进行读写操作;

跟踪fileChannle.map的方法发现最终调用的是FileChannelImpl.c里的方法;

继续跟踪这段代码,发现里面调用的mmap64这个系统函数,当mmap64返回的错误码是ENOMEM时,会向上抛出OOME,进一步查阅了GNU的手册,可以发现抛出ENOMEM错误码的解释:

1. 内存不足;

2. 地址空间不足。

而从当时的现场信息来看,这两点都不成立,当时没有新的思路,于是就先按照FileChannleImpl.unmap方法中的主动释放占用内存的方法改了下代码,改了后应用就一切正常了。

当天这个机器的JVM还crash了一次,crash日志中heap占用和物理内存都是非常正常,但日志中有个现象比较诡异: Dynamic libraries:这部分信息非常多,统计以后发现有65532条。

翻阅资料,发现这个数据来自 /proc/{pid}/maps, 这个文件展示了进程的虚拟地址空间的使用情况,这时突然想到ENOMEM中有说到进程的地址空间不足导致的,但是最后的7fff005aa000还远不到上限,而且计算虚拟内存占用也就几个G的空间。

这时想到前面提到65532这个数据,联想到了file-max,但是一查看是4889494,顺势猜想虚拟内存映射是不是也有打开上限? 不出所料果然是有限制的。

max_map_count这个参数就是允许一个进程在VMAs(虚拟内存区域)拥有最大数量,VMA是一个连续的虚拟地址空间,当进程创建一个内存映像文件时VMA的地址空间就会增加,当达到max_map_count了就是返回out of memory errors。

这个数据通过下面的命令可以查看:

cat /proc/sys/vm/max_map_count

发现应用所在的机器这个数值果然是65536,而且测试修改max_map_count后filechannel#map的个数的上限也随之变化。 所以可以确定程序OOM是由于达到了这个系统的上限,也就是ENOMEM错误码中所指的out of process address。

确定了异常的触发原因,再排查引发的原因就比较容易了,再看下FileChannleImp#map的代码,发现在map第一次出现OOM时,会显式的调用System.gc去回收,但不幸的是应用启动参数上是有-XX:+DisableExplicitGC的,所以就导致了map失败,但如果在代码里主动clean是ok的现象。

总结来说,这个异常出现的原因是:

数据量增长,导致map file个数增长,应用启动参数上有-XX:+DisableExplicitGC,导致了在map file个数到达了max_map_count后直接OOM了(这也是因为heap比较大,所以full gc触发的频率低,这个问题就特别容易暴露)。

从这个问题来看,启动参数上加-XX:+DisableExplicitGC确实还是要小心,不仅map file这里是在OOM后靠显式的去执行System.gc来回收,Direct ByteBuffer其实也是这样,而这两个场景都有可能因为java本身full gc执行不频繁,导致达到了限制条件(例如map file个数达到max_map_count,而Direct ByteBuffer达到MaxDirectMemorySize),所以在CMS GC的场景下,看来还是去掉这个参数,改为加上-XX:+ExplicitGCInvokesConcurrent这个参数更稳妥一点。

原文:http://www.cnblogs.com/jooyu/p/7466190.html

java map failed_java.lang.OutOfMemoryError:Map failed总结相关推荐

  1. java gc error_java.lang.OutOfMemoryError GC overhead limit exceeded原因分析及解决方案

    最近一个上线运行良好的项目出现用户无法登录或者执行某个操作时,有卡顿现象.查看了日志,出现了大量的java.lang.OutOfMemoryError: GC overhead limit excee ...

  2. java perm space_java.lang.OutOfMemoryError: PermGen space及其解决方法

    PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决 ...

  3. java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again

    文章目录 java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again异常分析及解决 问题描述: 问题分析: ...

  4. Android之java.lang.OutOfMemoryError: Failed to allocate a ** byte allocation with **free bytes and 2M

    1 问题 glide加载图片出现oom java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2 ...

  5. Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Compressed class space

    目录 主要得报错信息如下: 解决办法 主要得报错信息如下: 2022-05-16 07:56:47.702|ERROR|http-nio-8089-exec-11|46|c.g.d.npp.web.c ...

  6. 解决“java.lang.OutOfMemoryError: Failed to allocate a allocation until OOM”错误

    1.参考:解决"java.lang.OutOfMemoryError: Failed to allocate a allocation until OOM"错误_SEVENY_的博 ...

  7. Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space

    java.lang.OutOfMemoryError: Java heap space 解决方法 这个问题的根源是jvm虚拟机的默认Heap大小是64M,可以通过设置其最大和最小值来实现.设置的方法主 ...

  8. java outofmemory jsp_Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结...

    1.概念预热 首先了解几个概念 新生代:新创建的进程 老年代: 持久代:不会被回收 新生代:tofromeden-xms:堆内存空间的初始大小--XX:NewSize:新生代的初始空间大小-Xmx:堆 ...

  9. java.lang.OutOfMemoryError处理错误

    java.lang.OutOfMemoryError异常解决方法 原因: 常见的有以下几种: 1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据: 2.集合类中有对对象的引用,使用完后未清空, ...

  10. java.lang.OutOfMemoryError​异常解决方法

    java.lang.OutOfmemoryError: PermGen Space 的错误,导致项目无法正常运行. 出现这个错误的原因,总结一下: PermGen Space指的是内存的永久保存区,该 ...

最新文章

  1. 【radar】毫米波雷达静态障碍物识别及其相关资料(仿真、生成、标定、运动估计、静态障碍物识别)(3)
  2. 当了十年 IT 程序员,我转型做自动驾驶开发的这五年”_《新程序员》编辑部的博客-CSDN博客
  3. 用TensorFlow和TensorBoard从零开始构建ConvNet(CNN)
  4. Linux 文件查找(find)
  5. 【Java8】堆栈/队列/数组/链表/红黑树,List/set子接口,hashcode/hashset,Map/内部接口,/统计字符个数,debug,斗地主,Collections,TreeSet
  6. 在 VS Code 中轻松 review GitHub Pull Requests
  7. (30)System Verilog设计SPI发送
  8. 转 Xcode磁盘空间大清理
  9. cocos2d-x 3.2线程安全的消息中心
  10. z-buffer的概念和算法
  11. mseed读取[2]
  12. dnf仓库打不开怎么办,dnf仓库打不开_DNF仓库锁。设置之后,点了强制解除。然后仓库打不......
  13. SEM搜索引擎竞价全方位系统网课-优就业-专题视频课程
  14. 121 monogdb安装, 增删改查, mongodb中的update修改器 pymomgo
  15. ev3编程变量模块_【EV3基础编程 第八课】升阶学习难度,一对一个性化控制程序,变量来了...
  16. 计算机基础知识大全之硬件篇
  17. 【无标题】c++创建一个三角形类,计算周长和面积
  18. 【redis】ERR AUTH <password> called without any password configured for the default user解决
  19. 前端面试那些事【dt/dd、audio、onerror、标签、类、ID选择器、伪类选择器......
  20. 【转载】TCP/IP协议详解

热门文章

  1. Android Auto (AA)手机软件安装总结
  2. OpenCV入门(八)——形态学技术
  3. OJ 里面的 G++ 和C++ 到底有什么区别, 为什么有时候G++能过,C++不能过,而有时候C++能过,G++不能过?
  4. 这份免税的农产品销售发票,可以抵扣9%的增值税吗?
  5. 多大计算机科学世界排名,重磅!2021年QS世界大学学科排名发布!多大、UBC抢眼!这些专业最强!...
  6. 加拿大大学商用计算机专业,加拿大大学计算机专业排名详情
  7. html邮件和英文邮件,英文邮件中Best wishes和Best regards的区别
  8. 【机器学习】 吴恩达机器学习作业 ex1 python实现+Matlab实现
  9. Java 后台 google地图通过经纬度寻找地址
  10. js根据文字获取首字母案例,直接复制在html中即可查看效果