91名师指路-头部
91名师指路

OutOfMemoryError系列(四):java.lang.OutOfMemoryError: Direct buffer memory

由于某些原因,现在不支持支付宝支付,如需要购买源码请加博主微信进行购买,微信号:13248254750

Direct buffer memory异常演示

package com.mszl.oom;

import java.nio.ByteBuffer;

/**
* 功能:Direct buffer memory异常演示
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class DirectMemoryDemo {

public static void main(String[] args) {
System.out.println(" " + sun.misc.VM.maxDirectMemory() / (double)1024 / 1024 + " MB");
// 我们分配10M,实际只有5M,模拟java.lang.OutOfMemoryError: Direct buffer memory
ByteBuffer bb=ByteBuffer.allocateDirect(10 * 1024 * 1024);

}


}

maxDirectMemory方法调用的是rt.jar(D:\Program Files\Java\jdk1.8.0_231\jre\lib)中sun.misc包VM类中的。

eclipse里面设置的jvm参数

-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m

执行结果:

配置的maxDirectMemory 5.0 MB
[Full GC (System.gc()) [Tenured: 0K->506K(6848K), 0.0024130 secs] 723K->506K(9920K), [Metaspace: 1794K->1794K(4480K)], 0.0024728 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
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.mszl.oom.DirectMemoryDemo.main(DirectMemoryDemo.java:15)


导致原因:

(1)写NIO程序经常使用ByteBuffer来读取或者写入数据,这是一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

(2)ByteBuffer.allocate(capacity)第一种方式是分配JVM堆内存,属于GC管辖范围,由于需要拷贝所以速度相对较慢。

(3)ByteBuffer.allocateDirect(capacity)第二种方式是分配OS本地内存,不属于GC管辖范围,由于不需要内存拷贝所以速度相对较快。

(4)但如果不断分配本地内存,堆内存很少使用,那么JVM就不需要执行GC,DirectByteBuffer对象们就不会被回收,这时候堆内存充足,但本地内存可能已经使用光了,再次尝试分配本地内存就会出现OutOfMemoryError,那程序就直接崩溃了。


2019-12-13 17:58:21     阅读(1251)

名师出品,必属精品    https://www.91mszl.com

联系博主    
用户登录遮罩层
x

账号登录

91名师指路-底部