直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现。

在JDK 1.4中新加入NIO类,引入了一种基于通道(Channel 之前在写Socket程序的时候使用过)与缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内训,然后通过一个存储在Java堆中的DirectBuffer对象作为这块内存的引用进行操作。这样能在一场景中显著提高性能,因为避免了在Java堆中来回复制数据。

显然,本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,肯定还是会受到本机总内存(包括RAM和SWAP区域或者分页文件)大小以及处理器寻址空间的限制。服务器管理员在配置虚拟机参数时,会根据实际内存设置-Xmx等参数信息,但是经常忽略直接内存,使得各个内存区域总和大于物理内存限制 (包括物理的和操作系统级的限制),从而导致动态扩展时出现OutOFMemoryError异常。

本机直接内存溢出

1、直接内存不是运行时数据区域的一部分,也不是《Java虚拟机规范》中的定义的内存区域,但是也可能引发OutOfMemoryError异常。
2、在JDK1.4中引入NIO,引入了一种基于通道(Channel)和缓冲(Buffer)的I/O方式,可以使用Native函数分配堆外内存,然后通过一个存储在Java堆里的DirectByteBuffer对象作为这块内存的引用进行操作,从而提高性能,避免Java堆和Native堆中来回复制数据。
3、直接内存的容量大小可通过-XX:MaxDirectMemorySize参数来指定,如果不去指定,则默认与Java堆最大值一致。
4、有直接内存的溢出的明显特征就是在Heap Dump文件中不会看见什么明显的异常情况。


-XX:MaxDirectMemorySize(重点)

如果使用Java自带的 ByteBuffer.allocateDirect(size) 或者直接 new DirectByteBuffer(capacity) , 这样受-XX:MaxDirectMemorySize 这个JVM参数的限制. 其实底层都是用的Unsafe#allocateMemory,区别是对大小做了限制. 如果超出限制直接OOM.

如果通过反射的方式拿到Unsafe的实例,然后用Unsafe的allocateMemory方法分配堆外内存. 确实不受-XX:MaxDirectMemorySize这个JVM参数的限制 . 所以限制的内存大小为操作系统的内存.

如果不设置-XX:MaxDirectMemorySize 默认的话,是跟堆内存大小保持一致. [堆内存大小如果不设置的话,默认为操作系统的 1/4, 所以 DirectMemory的大小限制JVM的Runtime.getRuntime().maxMemory()内存大小 . ]


看深入理解java虚拟机的"本机直接内存溢出"一节中,容易误认为-XX:MaxDirectMemorySize这个参数对Unsafe的allocateMemory方法也有效,事实上并不是,这个参数只对Java自带的 ByteBuffer.allocateDirect(size) 或者直接 new DirectByteBuffer(capacity) 才有效。

Unsafe的allocateMemory方法限制的内存大小为操作系统的内存.


来源:

书: 深入理解java虚拟机

文章: [JVM]了断局: 堆外内存无法 [ -XX:MaxDirectMemorySize ] 限制

-XX:MaxDirectMemorySize直接内存无效问题相关推荐

  1. [JVM]了断局: 堆外内存无法 [ -XX:MaxDirectMemorySize ] 限制

    一. 前言 今天看到一句话 , 有点懵, 所以验证一下. 使用sun.misc.Unsafe的allocateMemory方法分配堆外内存.不受-XX:MaxDirectMemorySize这个JVM ...

  2. 聊聊jvm的-XX:MaxDirectMemorySize

    序 本文主要研究一下jvm的-XX:MaxDirectMemorySize -XX:MaxDirectMemorySize -XX:MaxDirectMemorySize=size用于设置New I/ ...

  3. JVM -XX:MaxDirectMemorySize

    -XX:MaxDirectMemorySize 该参数指定了DirectByteBuffer能分配的空间的限额,如果没有显示指定这个参数启动jvm,默认值是xmx对应的值. DirectByteBuf ...

  4. -XX:MaxDirectMemorySize

    -XX:MaxDirectMemorySize 最大堆外内存大小,此参数的含义是当Direct ByteBuffer分配的堆外内存到达指定大小后就触发Full GC. 首先可以在jdk文档中找到:关于 ...

  5. xx学OD -- 内存断点(上)

    这一篇讲的是 内存断点 上一篇学习函数参考的时候最后破解是这样子的. 0040132D |. 3BC6 CMP  EAX, ESI ;比较EAX和ESI的内容; 而ESI和EAX的值是经过一个加密算法 ...

  6. 老版本fortran语言 内存无效_面向科学计算的高性能动态编程语言 Julia

    Julia是一个新的高性能动态高级编程语言.语法和其他编程语言类似,易于其他语言用户学习.Julia拥有丰富的函数库,提供了数字精度.精致的增幅器(sophisticated amplifier)和分 ...

  7. 老版本fortran语言 内存无效_编程语言的分类

    编程语言世代 第一代和第二代语言又称低级语言(Low-level language),其余被视为高级语言(High-level language) 第一代编程语言 即机器语言,由0和1构成,通过面板. ...

  8. 一份关于jvm内存调优及原理的学习笔记

    JVM 一.虚拟机的基本结构 1.jvm整体架构 类加载子系统:负责从文件系统或者网络中加载class信息,存入方法区中. 方法区(Perm):存放加载后的class信息,包括静态方法,jdk1.6以 ...

  9. 程序员都应该知道的JVM参数

    Trace跟踪参数 1.-verbose:gc 2.-XX:+printGC 可以打印GC的简要信息 [GC 51790K->1374K(115872K), 0.0001606 secs] 3. ...

最新文章

  1. Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)
  2. 单片机怎么跳出循环_自学单片机第二十七篇:矩阵按键的硬件测试
  3. [C++] 指向常量的指针 VS 指针类型的常量
  4. Delphi保存网页中的图片
  5. python绘制饼图explode_python通过matplotlib生成复合饼图
  6. jsp session
  7. 阿里云大数据计算服务MaxCompute命令行工具——odpscmd的操作使用
  8. keil c语言绝对值函数,keil编写C程序是不是不能在函数内定义变量啊,求大神
  9. 大数据之-Hadoop3.x_MapReduce_区内排序案例---大数据之hadoop3.x工作笔记0117
  10. SQL:字符串拼接中换行处理
  11. 被逼至“盗版合法化”,俄罗斯要把 RuTracker 放出来了?
  12. 笨办法学C 练习43:一个简单的统计引擎
  13. Solidworks:Solidworks2016软件程序破解详细攻略说明(也适合长时间没使用SW2016再次破解)
  14. 智能手机屏幕尺寸和分辨率一览表
  15. Spring源码解析:Spring Aware 原理解析
  16. Mac电脑快速断网详细
  17. 初中计算机面试题目,2019年上半年教师资格证面试《初中信息技术》真题及答案...
  18. 易捷web文件服务器软件,易捷在线文件管理系统
  19. Autovue与后台的管理系统集成示例
  20. 关于遍历,看这篇文章就足够了【find()、findIndex()、forEach()、splice()、slice()详解】...

热门文章

  1. kbd_mode - 显示或者设置键盘模式
  2. 嵌入式产品如何支持阿拉伯文显示---看这一篇就够了
  3. Windows内核原理与实现之 NDIS(网络驱动程序接口规范)
  4. Type-C快充诱电方案(PD受电)
  5. POJ 1659 Frogs‘ Neighborhood (Havel 定理)
  6. 西安交通大学计算机专业考试科目,西安交通大学(专业学位)计算机技术研究生考试科目和考研参考书目...
  7. 淘宝一月上钻是这样操作的
  8. 714. [C++]买卖股票的最佳时机含手续费
  9. word文档画笔添加后灰色无法启用!
  10. spark 实现K-means算法