JVM direct memory

Java的ByteBuffer.allocateDirect()和Unsafe.allocateMemory()用于分配堆外内存,这部分内存受到-XX:MaxDirectMemorySize参数限制,默认与堆内存大小一致。若通过反射绕过限制,DirectMemory将受限于操作系统内存。不设置该参数时,最大DirectMemory为JVM的Runtime.getRuntime().maxMemory().

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhixingheyi_tian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值