最近发现个问题, 有点困惑,请指点:
Java程序使用 ByteBuffer.allocateDirect(1024 * 1024)分配500M直接内存(循环500次),在top -p或者在proc的VmRSS指标中 显示内存被占用(约500M的上涨);
反复继续分配-直到达到直接内存上限,抛出直接内存的OOM异常;此时VmRSS内存指标已达到一个峰值;
手动触发Full-GC来释放掉直接内存,此时VmRSS没有明显的下降(波动10M以内),而VisualVM通过Buffer Pool插件跟踪的直接内存下降了500M;
再次使用ByteBuffer.allocateDirect(500* 1024 * 1024) 分配成功,VmRSS和VisualVM的Buffer Pool同时上涨500M;不断进行(clear -> allocate),VmRSS会不断往上提升,远远超过直接内存上限;
逻辑代码如下所示:
private static final List<ByteBuffer> BUFFER_LIST = new ArrayList<>();
private void allocate(int n) {
for (int i = 0; i < n; i++) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024 * 1024);
BUFFER_LIST.add(byteBuffer);
}
}
private void clear() {
BUFFER_LIST.clear();
System.gc();
}