直接内存,不是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 合二为一。
网友评论