java中最大堆外内存大小MaxDirectMemorySize是个迷一样的,有说是64M,有说128M等等,那到底是怎么样的,我们通过官方文档和实际的代码测试一下。
首先可以在jdk文档中找到:docs.oracle.com/javase/8/do… 关于MaxDirectMemorySize内存的描述:
-XX:MaxDirectMemorySize=size
Sets the maximum total size (in bytes) of the New I/O (the java.nio package) direct-buffer allocations. Append the letter k or K to indicate kilobytes, m or M to indicate megabytes, g or G to indicate gigabytes. By default, the size is set to 0, meaning that the JVM chooses the size for NIO direct-buffer allocations automatically.
The following examples illustrate how to set the NIO size to 1024 KB in different units:
-XX:MaxDirectMemorySize=1m
-XX:MaxDirectMemorySize=1024k
-XX:MaxDirectMemorySize=1048576
就是说在默认情况下是0,JVM会自动申请内存的大小。但具体能够申请多大的内存没有描述清楚。
下面我们用代码测试一下,看到底能申请多大的内存。 主要的代码如下:
public class DirectMemoryTest {
public static void main(String[] args) throws InterruptedException {
int i = 0;
List<ByteBuffer> buffers = new ArrayList<>();
while (true) {
ByteBuffer bb = ByteBuffer.allocateDirect(1024 * 1024 * 1);
buffers.add(bb);
Thread.sleep(1000); //为了便于观察,休眠1s
System.out.println(i++);
}
}
}
先不设置任何参数,我们执行该代码,会发现一直执行下去 那接下来我们设置-XX:MaxDirectMemorySize=60M,运行代码:
0
...
58
59
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:694)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
at com.dada.app.config.util.MemoryTest.main(MemoryTest.java:14)
Process finished with exit code 1
发现在59的时候程序报了OutOfMemoryError的错误,可见MaxDirectMemorySize=60M是生效的。
继续回到不加参数时,那最大MaxDirectMemorySize究竟能申请多少,我们将最大堆内存设置为:-Xmx100M,然后继续运行看看。
94
95
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:694)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
at com.dada.app.config.util.MemoryTest.main(MemoryTest.java:14)
Process finished with exit code 1
结果在96M的时候就报错OutOfMemoryError,可见DirectMemorySize是受到-Xmx限制的。
那么最终结果就是在没有设置MaxDirectMemorySize大小时,默认是0,最大大小受限于-Xmx,如果设置了,那就是MaxDirectMemorySize的大小。
已经代码均在JDK8版本中测得,其他的版本还未进行过测试。