目录
-XX:MaxDirectMemorySize作用
用于设置直接内存的最大大小
在 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 to0
, meaning that the JVM chooses the size for NIO direct-buffer allocationsautomatically
.
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
什么是ByteBuffer?
ByteBuffer
是 Java NIO(New I/O)库中的一种重要数据结构,专门设计用来高效地处理字节序列
。
ByteBuffer分类
1、heap ByteBuffer
一种是heap ByteBuffer,该类对象分配在JVM的堆内存里面,直接由Java虚拟机负责垃圾回收,
2、direct ByteBuffer
一种是direct ByteBuffer,是通过 jni
在虚拟机外内存中分配的。通过 jmap 无法查看该块内存的使用情况。只能通过 top
来看它的内存使用情况。
如何设置 direct ByteBuffer
direct ByteBuffer可以通过-XX:MaxDirectMemorySize
来设置。默认大小等于-Xmx
。
用JDK8的一定要配置:-Xms -Xmx -XX:MaxDirectMemorySize
,Xmx + MaxDirectMemorySize
的值不能超过docker的最大内存,不然docker
内存占满了会被oomkill
掉;
「引」JVM参数之MaxDirectMemorySize
什么是BufferPool?
Buffer Pool 主要用于提高数据访问的效率,通过在内存中缓存
磁盘上的数据页,减少对物理磁盘的 I/O 操作次数,从而显著提升数据库系统的整体性能。
BufferPool 源码
// 提供对缓冲区使用情况信息的访问。
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();
}
}
启动VM options
-Xmx200m -Xms50m -XX:+PrintCommandLineFlags
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED
--add-opens java.base/jdk.internal.access=ALL-UNNAMED
结果分析
-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