JVM direct memory

JVM direct memory

如果使用Java自带的 ByteBuffer.allocateDirect(size) 或者直接 new DirectByteBuffer(capacity) , 这样受-XX:MaxDirectMemorySize 这个JVM参数的限制. 其实底层都是用的Unsafe#allocateMemory,区别是对大小做了限制. 如果超出限制直接OOM.

Unsafe.allocateMemory

如果通过反射的方式拿到Unsafe的实例,然后用Unsafe的allocateMemory方法分配堆外内存. 确实不受-XX:MaxDirectMemorySize这个JVM参数的限制 . 所以限制的内存大小为操作系统的内存.

// 启动参数: -Xmx20M -XX:MaxDirectMemorySize=10M
public class DirectMemoryOOM {
  private static final int _1MB = 1024 * 1024;

  public static void main(String[] args) throws Exception {
    Field unsafeField = Unsafe.class.getDeclaredFields()[0];
    unsafeField.setAccessible(true);
    Unsafe unsafe = (Unsafe) unsafeField.get(null);
    while (true) {
      unsafe.allocateMemory(_1MB);
    }
  }
}

这个代码并不产生异常

ByteBuffer.allocateDirect

如果不设置-XX:MaxDirectMemorySize 默认的话,是跟堆内存大小保持一致. [堆内存大小如果不设置的话,默认为操作系统的 1/4, 所以 DirectMemory的大小限制JVM的Runtime.getRuntime().maxMemory()内存大小

public class DirectMemoryOOM {
    // 分配直接内存大小为 20M
    private static final int size = 1024 * 1024*20;

    // 启动参数: -Xmx20M -XX:MaxDirectMemorySize=10M -XX:+HeapDumpOnOutOfMemoryError
    public static void main(String[] args) throws Exception {
        ByteBuffer.allocateDirect(size);
    }
}

Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
	at java.nio.Bits.reserveMemory(Bits.java:695)
	at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
	at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
	at com.jts.jvm.gc.oom.DirectMemoryOOM.main(DirectMemoryOOM.java:16)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: maxdirectmemorysize是Java虚拟机参数中的一个选项,用于设置直接内存的最大值。直接内存是一种不受Java大小限制的内存,通常用于NIO(New Input/Output)操作,如文件映射、网络传输等。该参数的默认值为-XX:MaxDirectMemorySize=,表示不限制直接内存的大小。可以通过设置该参数来控制直接内存的使用,避免出现内存溢出等问题。 ### 回答2: maxDirectMemorySize是JVM的一个参数,用于设置直接内存的最大大小。直接内存是指JVM在堆外分配的一块内存空间,用于存储一些特定的数据,如NIO中的缓冲区数据。 在Java虚拟机规范中,堆内存是通过Java对象进行分配的,而直接内存则是直接在操作系统的内存中进行分配。相比于堆内存,直接内存的访问速度更快,同时减少了垃圾收集器的压力。 maxDirectMemorySize参数的作用是限制直接内存的最大大小,超出这个限制将抛出OutOfMemoryError。这个参数的默认值与-Xmx参数的值相同,即堆内存的最大大小。可以通过在启动命令中使用"-XX:MaxDirectMemorySize"来设置直接内存的最大值。 需要注意的是,直接内存的分配由操作系统控制,因此直接内存的使用不受Java的垃圾回收机制管理。如果应用程序过度使用直接内存,可能会导致系统的内存不足。因此,在设置maxDirectMemorySize时,需要根据实际情况合理设置,避免过度使用直接内存而影响系统的稳定性。 总之,maxDirectMemorySize参数是用来限制直接内存的最大大小的,合理设置这个参数可以提高系统的性能和稳定性。 ### 回答3: maxDirectMemorySize是Java虚拟机(JVM)中用于限制直接内存大小的参数。直接内存是JVM运行时使用的一种特殊内存区域,不受Java大小的限制,并且可以通过ByteBuffer等类进行直接访问。 maxDirectMemorySize参数用于指定直接内存的最大大小,它的默认值与-Xmx参数(即堆的最大大小)相同。当JVM需要使用更大的直接内存时,会检查该参数是否足够大以满足需求。 设置maxDirectMemorySize参数的方法是通过在Java命令行中使用-XX:MaxDirectMemorySize参数,例如: java -XX:MaxDirectMemorySize=1g MyClass 以上命令将指定直接内存的最大大小为1GB。需要注意的是,该参数的单位可以是B(字节)、K(千字节)、M(兆字节)或G(吉字节),并且可以加上后缀B、K、M或G以指定具体的数值单位。 当maxDirectMemorySize参数设置的值超过系统实际可用的直接内存大小时,会抛出OutOfMemoryError异常提示内存不足。 在某些特殊情况下,如多线程高并发使用直接内存的场景中,可能需要通过调整maxDirectMemorySize参数来获取更大的直接内存空间,以避免出现内存溢出的情况。但是需要注意合理配置该参数,以免影响系统的稳定性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值