JVM内存管理---直接内存

直接内存,不是Java虚拟机规范中定义的内存区域,但是这一部分仍然会出现OutOfMemoryError异常。

JDK1.4中加入新的NIO(New Input/OutPut)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,可以通过Native函数库直接分配堆外内存,然后通过Java堆中的DirectByteBuffer对象来对这块内存的引用进行操作,避免数据在Java堆与Native堆中数据的来回复制。

本机的直接内存是有限制的,因此肯定也会由于内存不足造成OutOfMemoryError异常。

在JDK规范中存在的是方法区,但是HotSpot是通过PermGen Space(永久代)实现的。永久代仍存在于JDK1.7中,并没完全移除,譬如符号引用(Symbols)转移到了native heap;字面量(interned strings)转移到了java heap,String.intern()方法的实现也有变化;类的静态变量(class statics)转移到了java heap;在JDK1.8中,永久代被移除,取而代之的是元空间概念,也就是使用本地内存。

不断的使用String.intern()方法,在JDK1.6中会产生java.lang.OutOfMemoryError: PermGen space这个错误,在JDK1.7中就会报java.lang.OutOfMemoryError: Java Heap space,而在JDK1.8 中,也是java.lang.OutOfMemoryError: Java Heap space,但是还会多出warning:对参数PermSize以及MaxPermSize的设置已经从1.8中移除。

具体从永久代向元空间的转换原因如下:

1、字符串存在永久代中,容易出现性能问题和内存溢出。

2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。

3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。

4、Oracle 可能会将HotSpot 与 JRockit 合二为一。

你可能感兴趣的:(JVM内存管理---直接内存)