Java应用堆外内存、Unsafe与MaxDirectMemorySize技术答疑
JVM堆外内存控制相关问题解答
问题1:Unsafe API分配堆外内存的控制参数
- 核心控制参数是
-XX:MaxDirectMemorySize,Unsafe分配堆外内存时会受此参数限制。 - 没有专门针对Unsafe的其他独立控制参数,但
-Xmx(堆最大内存)会间接影响:当未显式设置MaxDirectMemorySize时,直接内存的默认最大值和-Xmx相关。
问题2:MaxDirectMemorySize与直接内存区域、Unsafe的关系
-XX:MaxDirectMemorySize就是用来控制JVM直接内存区域的最大大小。- Unsafe通过
allocateMemory等方法分配的堆外内存,属于直接内存区域,和NIO中DirectByteBuffer使用的是同一块内存空间。JVM会跟踪该区域的使用量,当接近阈值时会触发垃圾回收来释放不再被引用的直接内存对象。
问题3:未设置MaxDirectMemorySize时的默认大小
- 如果未显式配置
-XX:MaxDirectMemorySize,默认值等于-Xmx(堆最大内存)的设定值。例如设置-Xmx2g时,直接内存的默认最大限制也是2G,该值在JVM启动时确定,不会动态调整。
问题4:Unsafe分配超出限制的内存是否会OOM
- 会触发
OutOfMemoryError。当Unsafe尝试分配的内存超过MaxDirectMemorySize限制时,JVM会先尝试触发Full GC回收闲置的直接内存;若GC后仍无法腾出足够空间,就会抛出OOM异常。 - 注意:Unsafe分配的内存不会自动回收,必须手动调用
freeMemory方法释放,否则即使对应的Java对象被回收,内存也不会归还操作系统,容易引发内存泄漏并最终导致OOM。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

