案例

一个网站为了实现客户端实时从服务端接收数据,使用了 CometD 1.1.1 作为服务端推送框架,服务器是 Jetty7.1.4,CPU i5,内存 4G,操作系统 32位Windows。

服务端常常抛出内存溢出异常,管理员把堆开到最大(32位系统最多到1.6G),但问题依旧。

开着 jstat 观察,GC并不频繁,eden、survivor、老年代、永久代的内存都很正常,没有压力。

查看日志中有异常信息:

...

java.lang.OutOfMemoryError:null

...

at java.nio.DirectByteBuffer ...

原因

这是由 Direct Memory 不足引起的。

操作系统对每个进程能管理的内存是有限制的,32位windows的限制是2G,其中1.6G给了Java堆,但 Direct Memory 是不计入这 1.6G的,因此 Direct Memory 最大就是 0.4G。

垃圾回收时,虽然会对 Direct Memory 进行回收,但不像新生代、老年代那样,发现空间不足时就触发回收,只能等老年代满了之后 full gc 时,随便把 Direct Memory 清理一下,否则只能等抛出异常后进行catch,调用 System.gc()。

这个案例中使用了 CometD,有大量的 NIO 使用 Direct Memory,所以产生了这个问题。

总结

我们平时对堆比较关注,但一定要记得,除了堆之外,下面这些区域也会占用较多的内存,需要注意:

Direct Memory

可以通过 -XX:MaxDirectMemorySize调整大小,内存不足时抛出 OutOfMemoryError或者OutOfMemoryError:Direct buffer memory

线程堆栈

可通过 -Xss调整大小,内存不足时抛出 StackOverflowError(纵向无法分配,即无法分配新的栈帧)或者OutOfMemoryError:unable to create new native thread(横向无法分配,即无法建立新的线程)

Socket 缓存区

每个socket连接都有 receive 和 send 两个缓存区,分别占大约 37K 和 25K,连接多时占用的内存也很可观,如果无法分配,抛出异常 IOException: Too many open files 。

java堆外内存溢出_JVM 案例 - 堆外内存导致的溢出错误相关推荐

  1. Java内存溢出故障案例及Linux内存机制探究

    文章目录 Java内存溢出故障案例及Linux内存机制探究 OOM Killer触发机制分析 如何避免系统触发OOM Killer 这部分内容属于demo案例分享,解决线上运维问题,思路是最重要的 J ...

  2. java 内存压缩_JVM之指针压缩内存如何设置

    在32位到64位的转变中,人们最大的获益是内存容量.在一个32位的系统中,内存地址的宽度就是32位,这就意味着,我们最大能获取的内存空间是2^32(也就是4G)字节.这个容量明显不够用!在一个64位的 ...

  3. 45.JVM调优策略、常见问题:内存泄漏(年老代堆空间被占满、持久代被占满、堆栈溢出、线程堆栈满、系统内存被占满)优化方法:优化目标、优化GC步骤、优化总结;案例分析(公司系统参数、网上给的配置参数)

    45.JVM调优策略 45.1.常见问题 45.1.1.内存泄漏 45.1.1.1.年老代堆空间被占满 45.1.1.2.持久代被占满 45.1.1.3.堆栈溢出 45.1.1.4.线程堆栈满 45. ...

  4. java堆是gc管理_JVM内存管理及GC机制

    一.概述 JavaGC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露和 ...

  5. java堆外内存详解(又名直接内存)和ByteBuffer

    堆内内存 java的内存分为堆内内存和堆外内存,在了解堆外内存之前,先看看堆内内存是啥,堆内内存是受jvm管控的,也就是说,堆内内存由jvm负责创建和回收:创建和回收都是自动进行的,不需要人为干预: ...

  6. bat java 指定堆大小_jvm 堆内存 栈内存 大小设置 查看堆大小

    1.在eclipse设置JVM参数 打开eclipse-窗口-首选项-Java-已安装的JRE(对在当前开发环境中运行的java程序皆生效,也就是在eclipse中运行的java程序)编辑当前使用的J ...

  7. java gc堆中的分区_jvm内存各个区域详解

    内存区域划分 Java虚拟机所管理的内存区域分为如下部分:方法区.GC堆.虚拟机栈.本地方法栈.PC程序计数器. 其中方法区.GC堆是所有线程共享的:虚拟机栈.本地方法栈.PC程序计数器是各个线程独占 ...

  8. java保证一段代码枷锁_Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM ...

  9. 五种内存溢出案例总结:涵盖栈深度溢出、永久代内存溢出、本地方法栈溢出、JVM栈内存溢出和堆溢出

    大家好,我是冰河~~ 相信小伙伴们在平时工作的过程中,或多或少都会遇到一个场景:内存溢出.如果你没有遇到过这个场景,那就说明你是个假的程序员.哈哈,开个玩笑,平时工作过程中,我们确实会遇到这个问题.今 ...

最新文章

  1. javascript元素跟随鼠标在指定区域运动
  2. 使用 Spring Boot 快速构建 Spring 框架应用--转
  3. 043 hive数据同步到mysql
  4. python和jupyter安装
  5. spark的java源码,Spark源码包的编译
  6. Java多线程并发——CAS和AQS
  7. flashBuilder安装Subclipse与XMLBuddy插件
  8. InteliJ Idea通过maven创建webapp
  9. $.ajax()方法详解(转)
  10. Valid Palindrome LeetCode Java
  11. 【软考软件评测师】历年真题大汇总
  12. DirectX SDK 2010 , DXSDK_Jun10.exe, 下载地址
  13. java判断来源_java中判断applet 来源的方法有()
  14. 大学如何自学计算机科学与技术?
  15. 手机长度px值_html长度尺寸单位px像素
  16. 解决Spring Spring Data JPA 错误: Page 1 of 1 containing UNKNOWN instances
  17. SQL server2012 安装
  18. 股市The Stock Market
  19. 【解决方案】公安网内网如何通过国标GB28181协议将视频流对接至公众号进行直播?
  20. 计算机怎么检测扫描机,如何对扫描仪进行常规的检测 -电脑资料

热门文章

  1. 跟面试官侃了半小时 MySQL 事务,把原子性、一致性、持久性的实现都讲完了
  2. OpenStack精华问答 | OpenStack的目标是什么?
  3. apache 统计404日志_Apache监控与调优(四)Apachetop监控
  4. 什么叫做石英表_石英表 是什么意思??
  5. redio中插入php脚本,Jquery操作radio的简单实例
  6. wangeditor 使用
  7. linux环境安装Kafka最新版本 jdk1.8
  8. 创新小组 实战Git团队企操作手册_精华版本
  9. RabbitMQ的5种队列_Work模式_入门试炼_第5篇
  10. 解决 idea 运行 Spring Boot 项目启动慢的问题