0%

java | 原理「溢出、释放」

根据 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 线程通过 Cleanerclean 方法调用 freeMemory 来释放直接内存。

请我喝杯咖啡吧~