根据 java | 直接内存
直接内存是没有垃圾回收的,所以,其也存在内存溢出。
内存溢出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.redisc;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List;
@Slf4j(topic = "c.Run") public class Run {
static final int _100MB = 1024 * 1024 * 100;
public static void main(String[] args) throws IOException { List<ByteBuffer> list = new ArrayList<>(); while (true) { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_100MB); list.add(byteBuffer); } }
}
|
输出
1 2 3 4 5
| 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.redisc.Run.main(Run.java:19)
|
释放原理
直接内存是通过 unsafe
对象进行回收的,和 gc
没有关系。
回收需要主动调用 freeMemory
方法。
ByteBuffer
的实现类内部,使用了 Cleaner
(虚引用)来检测 ByteBuffer
对象,一旦 ByteBuffer
对象被垃圾回收了,那么,就会由 ReferenceHandler
线程通过 Cleaner
的 clean
方法调用 freeMemory
来释放直接内存。