序 本文主要研究一下netty的maxDirectMemory(io.netty.maxDirectMemory) reactive-server-with-netty-76-638.jpg PlatformDependent long maxDirectMemory = SystemPropertyUtil.getLong("io.netty.maxDirectMemory", -1); if (maxDirectMemory : {} bytes", maxDirectMemory); DIRECT_MEMORY_LIMIT = maxDirectMemory >= 1 ? 到maxDirectMemory,如果maxDirectMemory值小于0,则设置maxDirectMemory为MAX_DIRECT_MEMORY;DIRECT_MEMORY_LIMIT = maxDirectMemory 到maxDirectMemory,如果maxDirectMemory值小于0,则设置maxDirectMemory为MAX_DIRECT_MEMORY;DIRECT_MEMORY_LIMIT = maxDirectMemory
序 本文主要研究一下netty的maxDirectMemory(io.netty.maxDirectMemory) PlatformDependent netty-common-4.1.33.Final-sources.jar long maxDirectMemory = SystemPropertyUtil.getLong("io.netty.maxDirectMemory", -1); if (maxDirectMemory : {} bytes", maxDirectMemory); DIRECT_MEMORY_LIMIT = maxDirectMemory >= 1 ? 到maxDirectMemory,如果maxDirectMemory值小于0,则设置maxDirectMemory为MAX_DIRECT_MEMORY;DIRECT_MEMORY_LIMIT = maxDirectMemory 到maxDirectMemory,如果maxDirectMemory值小于0,则设置maxDirectMemory为MAX_DIRECT_MEMORY;DIRECT_MEMORY_LIMIT = maxDirectMemory
. // public static long maxDirectMemory() { return directMemory; } //...... -1,那么则设置为Runtime.getRuntime().maxMemory();如果有设置MaxDirectMemorySize且值大于-1,那么使用该值作为directMemory的值;而VM的maxDirectMemory 方法则返回的是directMemory的值 获取maxDirectMemory的值 实例 public BufferPoolMXBean getDirectBufferPoolMBean(){ java.base/jdk/internal/misc/VM.java中可以看到默认是取的Runtime.getRuntime().maxMemory() 使用jdk.internal.misc.VM.maxDirectMemory ()可以获取maxDirectMemory的值;由于java9模块化之后,VM从原来的sun.misc.VM变更到java.base模块下的jdk.internal.misc.VM;上面代码默认是unamed
他使用netty进行网络通信 //2)lettuce的bug导致netty堆外内存溢出 netty如果没有指定堆外内存,默认使用-Xmx //可以通过-Dio.netty.maxDirectMemory 进行设置 //解决方案:不能使用-Dio.netty.maxDirectMemory只去调大 //1)升级lettuce //2)切换使用jedis //lettuce jedis操作redis底层的客户端
都是带有 Cleaner 的,这种情况下 Netty 并不会限制 maxDirectMemory 的用量,因为限制了也没用,具体能用多少 maxDirectMemory,还是由 JVM 参数 -XX: 这里需要特别注意的是,Netty 层面对于 maxDirectMemory 的容量限制和 JVM 层面对于 maxDirectMemory 的容量限制是单独分别计算的,互不影响。 io.netty.maxDirectMemory > 0 的情况和小于 0 的情况一样,唯一不同的是 Netty 层面的 maxDirectMemory 用量是专门由 -Dio.netty.maxDirectMemory (); static { long maxDirectMemory = SystemPropertyUtil.getLong("io.netty.maxDirectMemory : {} bytes", maxDirectMemory); DIRECT_MEMORY_LIMIT = maxDirectMemory >= 1 ?
void reserveMemory(long size, int cap) { // 初始化maxMemory,如果没有指定-XX:MaxDirectMemorySize, // 就使用VM.maxDirectMemory MEMORY_LIMIT_SET && VM.initLevel() >= 1) { MAX_MEMORY = VM.maxDirectMemory(); MEMORY_LIMIT_SET
memoryLimitSet && VM.isBooted()) { maxMemory = VM.maxDirectMemory(); memoryLimitSet 代码中maxMemory = VM.maxDirectMemory(); private static long directMemory = 64 * 1024 * 1024; //64MB public static long maxDirectMemory() { return directMemory; } 实际上在 JVM启动时,会对System做初始化,实际上堆外内存的大小设置逻辑为
DirectBufferMemoryDemo { public static void main(String[] args) { System.out.println("maxDirectMemory is:"+sun.misc.VM.maxDirectMemory() / 1024 / 1024 + "MB"); //ByteBuffer buffer = ByteBuffer.allocate maxDirectMemory is:5MB Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory 4.2
System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024.0); System.out.println(VM.maxDirectMemory
DirectBufferMemoryDemo { public static void main(String[] args) { System.out.println("maxDirectMemory is:"+sun.misc.VM.maxDirectMemory() / 1024 / 1024 + "MB"); //ByteBuffer buffer = ByteBuffer.allocate maxDirectMemory is:5MB Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory 4.2
DirectBufferMemoryDemo { public static void main(String[] args) www.javachenglei.com { System.out.println("maxDirectMemory is:"+sun.misc.VM.maxDirectMemory() / 1024 / 1024 + "MB"); //ByteBuffer buffer = ByteBuffer.allocate maxDirectMemory is:5MB Exception in thread www.xingyunylpt.com"main" java.lang.OutOfMemoryError: Direct
sun.arch.data.model) [DEBUG]Slf4JLogger--Dio.netty.noPreferDirect: false [DEBUG]Slf4JLogger--Dio.netty.maxDirectMemory
在Java 11 上,它将从 Java 直接内存池中分配内存,并受 MaxDirectMemory限制。当前的Pulsar客户端没有用于控制内存限制的配置选项,这可能导致OOM。
* 报错:java.lang.OutOfMemoryError: Direct buffer memory */ // System.out.println("配置的maxDirectMemory : " + (sun.misc.VM.maxDirectMemory() / (double) 1024 / 1024) + "MB"); // //最大5M 申请6M //
该值是有上限的,默认是64M,最大为sun.misc.VM.maxDirectMemory()。
memoryLimitSet && VM.isBooted()) { maxMemory = VM.maxDirectMemory(); memoryLimitSet DirectByteBuffer通过sun.misc.VM#maxDirectMemory来获取这个值,可以看一下对应的代码: // A user-settable upper limit on the //public static long maxDirectMemory() { return directMemory;} 这里directMemory默认赋值为64MB,那对外内存的默认大小是
注意该值是有上限的,默认是64M,最大为sun.misc.VM.maxDirectMemory(),在程序中中可以获得-XX:MaxDirectMemorySize的设置的值。
=5m public class DirectBufferDemo { public static void main(String[] args) { System.out.println("maxDirectMemory : " + sun.misc.VM.maxDirectMemory() / (1024 * 1024) + "MB"); ByteBuffer byteBuffer = ByteBuffer.allocateDirect (6 * 1024 * 1024); } }Copy to clipboardErrorCopied 输出 maxDirectMemory : 5MB [GC (System.gc()) [PSYoungGen
memoryLimitSet && VM.isBooted()) { maxMemory = VM.maxDirectMemory(); memoryLimitSet
UNSAFE_UNAVAILABILITY_CAUSE中 DIRECT_BUFFER_PREFERRED 默认优先使用堆外内存分配 MAX_DIRECT_MEMORY 获取最大堆外内存通过sun.misc.VM#maxDirectMemory