原 OutOfMemoryError系列(四):java.lang.OutOfMemoryError: Direct buffer memory
版权声明:本文为博主原创文章,请尊重他人的劳动成果,转载请附上原文出处链接和本声明。
本文链接:https://www.91mszl.com/zhangwuji/article/details/1174
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 阅读(1385)
名师出品,必属精品 https://www.91mszl.com
博主信息