原文:http://dongliu.net/post/504141
几台服务器的JVM占用内存总是持续增长,大大超过-Xmx设定的值,服务器物理内存几乎被耗尽。
使用jmap查看JVM的内存使用,发现jvm的堆大小完全在-Xmx参数设定的范围之内,那问题只能处在别的地方了。
JVM除了堆内存之外,就只有栈内存和DirectMemory了。栈空间每个线程是固定的,线程数也没可能多到可以占用这么多内存的程序,所以怀疑的目标就在DirectMemory上了。
DirectMemory是java nio引入的,直接以native的方式分配内存,不受jvm管理。这种方式是为了提高网络和文件IO的效率,避免多余的内存拷贝而出现的。DirectMemory占用的大小没有直接的工具或者API可以查看,不过这个在Bits类中是有两个字段存储了最大大小和已分配大小的,使用反射可以拿到这个数据:
Class<?> c = Class.forName("java.nio.Bits");
Field maxMemory = c.getDeclaredField("maxMemory");
maxMemory.setAccessible(true);
Field reservedMemory = c.getDeclaredField("reservedMemory");
reservedMemory.setAccessible(true);
Long maxMemoryValue = (Long)maxMemory.get(null);
Long reservedMemoryValue = (Long)reservedMemory.get(null);
Field maxMemory = c.getDeclaredField("maxMemory");
maxMemory.setAccessible(true);
Field reservedMemory = c.getDeclaredField("reservedMemory");
reservedMemory.setAccessible(true);
Long maxMemoryValue = (Long)maxMemory.get(null);
Long reservedMemoryValue = (Long)reservedMemory.get(null);
结果证实了猜测,DirectMemory增长失控了。
原来,DirectMemory 的默认大小是64M,而JDK6之前和JDK6的某些版本的SUN JVM,存在一个BUG,在用-Xmx设定堆空间大小的时候,也设置了DirectMemory的大小。加入设置了-Xmx2048m,那么jvm最终可分配的内存大小为4G多一些,是预期的两倍。
解决方式是设置jvm参数-XX:MaxDirectMemorySize=128m,指定DirectMemory的大小。
相关推荐
10. **堆外内存管理**:在某些场景下,直接内存(Direct Memory)能提供更快的I/O性能,但需要正确设置`-XX:MaxDirectMemorySize`以防止溢出。 以上就是关于“jvm设置2”的一些关键知识点,通过理解和调整这些设置...
- **直接内存(Direct Memory)**:不在JVM内存区内,通过`java.nio.ByteBuffer.allocateDirect()`方式分配内存。 ##### 2. HotSpot运行时数据区域关系图 HotSpot虚拟机是Sun Microsystems开发的一款高性能的JVM实现...
7. **直接内存(Direct Memory)** 不属于JVM规范定义的内存区域,但在高性能应用中常见,如NIO(New Input/Output)库,通过直接内存可以绕过Java堆,提高性能。 了解这些内存区域的工作原理和交互方式,可以帮助...
- **直接内存(Direct Memory)**:不是JVM运行时数据区的一部分,但在某些场景下会被频繁使用,比如通过ByteBuffer的allocateDirect方法分配的内存。 #### 堆内存划分与回收 堆内存通常被划分为几个部分,包括...
直接内存(Direct Memory)是一块物理内存,它不是JVM虚拟机的运行时数据区的一部分,但是它经常被用来存储大型数据。直接内存可以通过Unsafe类或Netty框架来操作。 OutOfMemoryError OutOfMemoryError是一种常见...
6. 直接内存(Direct Memory):并非JVM运行时数据区的一部分,它通过NIO类库支持直接操作本地内存,并不是JVM规范所定义的。 JVM内存模型的设计是为了支持Java程序的动态特性,同时保证内存的安全和高效利用。JVM...
- **Direct Memory OutOfMemory**:直接内存溢出时发生。可以通过增加`-XX:MaxDirectMemorySize`的值来增大最大直接内存大小。 2. **JVM内存模型**: - JVM内存模型主要包括堆内存、栈内存、方法区和程序计数器。...
6. **直接内存(Direct Memory)** - 不属于JVM的运行时数据区域,但对性能有很大影响,通过Native函数库直接分配堆外内存,减少数据复制。 7. **内存分配策略** - 对象一般在Eden区创建,当Eden区满时触发Minor ...
- 直接内存(Direct Memory)不是JVM内存的一部分,但通过NIO可以使用,不计入堆内存计算。 了解这些概念有助于优化Java应用性能,减少内存泄漏和提高程序效率。在实际开发中,理解JVM的工作原理对于解决内存问题...
7. **直接内存(Direct Memory)**:不在JVM规范中定义,但现代JVM通常使用它来提高性能,尤其是在处理大容量数据时。通过NIO(New Input/Output)库,Java程序可以直接访问操作系统内存,避免了JVM堆的内存分配和...
直接内存(Direct Memory):不是虚拟机运行时数据区的一部分,也不是 java 虚拟机规范中定义的内存区域;如果使用了 NIO,这块区域会被频繁使用,在 java 堆内可以用 directByteBuffer 对象直接引用并操作;这块内存...
- 直接内存(Direct Memory):使用Native方法直接分配堆外内存。 4. **垃圾收集** - 垃圾收集的基本概念与目标。 - 垃圾收集器类型:串行、并行、并发、G1、ZGC、Shenandoah等。 - 分代收集理论:年轻代、老...
6. 直接内存(Direct Memory):并非由JVM直接管理的内存区域,它与Java堆内存区分开来,通过NIO类库进行直接内存的分配。 二、内存管理机制 1. StringTable:JVM中的常量池用于存储编译期生成的各种字面量和符号...
在JVM的内存模型中,直接内存(Direct Memory)是一个特殊的区域,虽然它并不属于标准的JVM运行时数据区,但对高性能的应用程序设计有着重要的影响。本文将深入探讨直接内存的概念、用途、优缺点以及如何进行配置。 ...
元空间位于直接内存(Direct Memory),这使得内存分配更加灵活,同时提高了垃圾回收的效率。 方法区和永久代的关系并不完全等同,方法区是一个逻辑概念,而永久代是物理堆内存中的一块区域,负责存储字节码、静态...
3. **直接内存(Direct Memory)**: - 不属于JVM的运行时数据区,但与JVM交互密切。通过NIO,可以直接在堆外分配内存,减少Java堆与Native堆之间的数据复制。直接内存受限于系统总内存和处理器寻址空间,过大可能...
6. **直接内存(Direct Memory)**:非JVM堆内存的一部分,但对性能有显著影响。通过NIO(New Input/Output)库可以直接在直接内存中分配和读写,避免了Java堆和本地堆之间的数据复制。 `bin`工具是Java开发中用于...
OutOfMemoryError 异常有多种场景,包括 java.lang.OutOfMemoryError: Java heap space、java.lang.OutOfMemoryError: GC overhead limit exceeded 和 java.lang.OutOfMemoryError: Direct buffer memory 等。