-XX:MaxDirectMemorySize |
---|
最大堆外内存大小,此参数的含义是当Direct ByteBuffer分配的堆外内存到达指定大小后就触发Full GC 。 |
首先可以在jdk文档中找到:关于MaxDirectMemorySize内存的描述: |
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 |
参考 |
关于JDK8中最大堆外内存大小MaxDirectMemorySize |
文章来源:https://uudwc.com/A/EBP6m
ByteBuffer(字节缓冲区)分类
heap ByteBuffer -> -XX:Xmx |
---|
一种是heap ByteBuffer,该类对象分配在JVM的堆内存里面,直接由Java虚拟机负责垃圾回收, |
direct ByteBuffer -> -XX:MaxDirectMemorySize |
一种是direct ByteBuffer是通过jni在虚拟机外内存中分配的。通过jmap无法查看该快内存的使用情况。只能通过top来看它的内存使用情况。 |
JVM堆内存大小可以通过-Xmx 来设置 |
direct ByteBuffer可以通过-XX:MaxDirectMemorySize 来设置 |
没有配置MaxDirectMemorySize的,默认MaxDirectMemorySize的大小即等于-Xmx |
用JDK8的一定要配置:-Xms -Xmx -XX:MaxDirectMemorySize ,【Xmx + MaxDirectMemorySize】的值不能超过docker的最大内存,不然docker内存占满了会被oomkill掉; |
参考 |
JVM参数之MaxDirectMemorySize |
启动VM options
-Xmx200m
-Xms50m
-XX:+PrintCommandLineFlags
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED
--add-opens java.base/jdk.internal.access=ALL-UNNAMED
文章来源地址https://uudwc.com/A/EBP6m
背景了解
// 提供对缓冲区使用情况信息的访问。
public interface BufferPool {
String getName();
long getCount();
long getTotalCapacity();
long getMemoryUsed();
}
// The management interface for a buffer pool
public interface BufferPoolMXBean extends PlatformManagedObject {
// The name of this buffer pool
String getName();
// An estimate of the number of buffers in this pool
long getCount();
// An estimate of the total capacity of the buffers in this pool in bytes
long getTotalCapacity();
// An estimate of the memory that the JVM is using for this buffer pool in bytes,
// or -1L if an estimate of the memory usage is not available
long getMemoryUsed();
练习代码
public class MaxDirectMemorySize {
public static void main(String[] args) {
printJVMRuntime();
printDirectMemory();
System.out.println("分配25M本地字节缓冲区 " + ByteBuffer.allocateDirect(25 * 1024 * 1024));
System.out.println("创建10M对象 " + new byte[10 * 1024 * 1024]);
printJVMRuntime();
printDirectMemory();
System.out.println("分配25M本地字节缓冲区 " + ByteBuffer.allocateDirect(25 * 1024 * 1024));
System.out.println("创建10M对象 " + new byte[10 * 1024 * 1024]);
printJVMRuntime();
printDirectMemory();
}
private static void printJVMRuntime() {
System.out.println("java虚拟机从操纵系统那里挖到的最大的内存 maxMemory " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "M");
System.out.println("java虚拟机已经从操作系统那里挖过来的内存 totalMemory : " + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "M");
System.out.println("java虚拟机从操纵系统挖过来还没用上的内存 freeMemory : " + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "M");
}
private static void printDirectMemory() {
System.out.println("the maximum allocatable direct buffer memory: " + VM.maxDirectMemory() / 1024 / 1024 + "M");
System.out.println("BufferPoolMXBean.Name: " + getDirectBufferPoolMBean().getName());
System.out.println("BufferPoolMXBean.Count: " + getDirectBufferPoolMBean().getCount());
System.out.println("BufferPoolMXBean.TotalCapacity: " + getDirectBufferPoolMBean().getTotalCapacity() / 1024 / 1024 + "M");
System.out.println("BufferPoolMXBean.MemoryUsed: " + getDirectBufferPoolMBean().getMemoryUsed() / 1024 / 1024 + "M");
System.out.println("BufferPool.Name: " + getNioBufferPool().getName());
System.out.println("BufferPool.Count: " + getNioBufferPool().getCount());
System.out.println("BufferPool.TotalCapacity: " + getNioBufferPool().getTotalCapacity() / 1024 / 1024 + "M");
System.out.println("BufferPool.MemoryUsed: " + getNioBufferPool().getMemoryUsed() / 1024 / 1024 + "M");
}
public static BufferPoolMXBean getDirectBufferPoolMBean() {
return ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class).stream().filter(e -> e.getName().equals("direct")).findFirst().orElseThrow();
}
public static VM.BufferPool getNioBufferPool() {
return SharedSecrets.getJavaNioAccess().getDirectBufferPool();
}
}
结果分析
-XX:ConcGCThreads=3 -XX:G1ConcRefinementThreads=13 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=52428800 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=209715200 -XX:MinHeapSize=52428800 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation |
---|
java虚拟机从操纵系统那里挖到的最大的内存 maxMemory 200M
java虚拟机已经从操作系统那里挖过来的内存 totalMemory : 50M
java虚拟机从操纵系统挖过来还没用上的内存 freeMemory : 45M
the maximum allocatable direct buffer memory: 200M
BufferPoolMXBean.Name: direct
BufferPoolMXBean.Count: 1
BufferPoolMXBean.TotalCapacity: 0M
BufferPoolMXBean.MemoryUsed: 0M
BufferPool.Name: direct
BufferPool.Count: 1
BufferPool.TotalCapacity: 0M
BufferPool.MemoryUsed: 0M
分配25M本地字节缓冲区 java.nio.DirectByteBuffer[pos=0 lim=26214400 cap=26214400]
创建10M对象 [B@5f4da5c3
java虚拟机从操纵系统那里挖到的最大的内存 maxMemory 200M
java虚拟机已经从操作系统那里挖过来的内存 totalMemory : 50M
java虚拟机从操纵系统挖过来还没用上的内存 freeMemory : 33M
the maximum allocatable direct buffer memory: 200M
BufferPoolMXBean.Name: direct
BufferPoolMXBean.Count: 2
BufferPoolMXBean.TotalCapacity: 25M
BufferPoolMXBean.MemoryUsed: 25M
BufferPool.Name: direct
BufferPool.Count: 2
BufferPool.TotalCapacity: 25M
BufferPool.MemoryUsed: 25M
分配25M本地字节缓冲区 java.nio.DirectByteBuffer[pos=0 lim=26214400 cap=26214400]
创建10M对象 [B@443b7951
java虚拟机从操纵系统那里挖到的最大的内存 maxMemory 200M
java虚拟机已经从操作系统那里挖过来的内存 totalMemory : 50M
java虚拟机从操纵系统挖过来还没用上的内存 freeMemory : 22M
the maximum allocatable direct buffer memory: 200M
BufferPoolMXBean.Name: direct
BufferPoolMXBean.Count: 3
BufferPoolMXBean.TotalCapacity: 50M
BufferPoolMXBean.MemoryUsed: 50M
BufferPool.Name: direct
BufferPool.Count: 3
BufferPool.TotalCapacity: 50M
BufferPool.MemoryUsed: 50M