Java 内存之直接内存 — 漠然

Java 内存之直接内存

2016/03/22 JMM

一、概念和特征

  • 直接内存并非 JVMS 定义的标准 Java 运行时内存。
  • JDK1.4 加入了新的 NIO 机制,目的是防止 Java 堆 和 Native 堆之间往复的数据复制带来的性能损耗,此后 NIO 可以使用 Native 的方式直接在 Native 堆分配内存。
  • 直接内存区域是全局共享的内存区域。
  • 直接内存区域可以进行自动内存管理(GC),但机制并不完善。
  • 本机的 Native 堆(直接内存) 不受 JVM 堆内存大小限制。
  • 可能出现 OutOfMemoryError 异常。

二、异常演示

测试代码:


public class TestNativeHeap {

	/**
	 * VM Args: -XX:MaxDirectMemorySize=10M
	 */

	// 每次内存分配大小
	private static int _1M =1024*1024;

	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
		Field unsafeFiled = Unsafe.class.getFields()[0];
		unsafeFiled.setAccessible(true);
		Unsafe unsafe = (Unsafe) unsafeFiled.get(null);
		while (true) {
			unsafe.allocateMemory(_1M);
		}
	}
}

以上代码运行会出现 OutOfMemoryError 异常,原因是不断申请内存将超出 Native 堆限制。

直接内存导致的 OutOfMemoryError 异常,在异常信息中不会有明显的堆栈区错误提示;同时另一大特点就是内存转储文件(dump)出来会非常小,如果项目中出现这种情况,并且直接或者间接地使用了 NIO 技术,那么应该考虑是否为直接内存导致的内存溢出。 转载请注明出处,本文采用 CC4.0 协议授权

Search

    Post Directory