方法区(接口)->元数据(实现)
1可以不进行垃圾回收和碎片压缩
2大小可确定也可以运行的时候动态扩展(扩展和压缩)
3存储物理可不连续,逻辑要连续(和堆一样各个线程共享),关闭jvm的时候就释放了
4存储类型(class)信息
5类的元数据保存在本地堆空间之中,这块区域被称为元数据区(和永久代不同,元数据区不适用java虚拟机的内存而是使用本地内存)跟不容易出现OOM。
6MataspaceSize初始值设置成为一个相对较高的一个值
7内存泄漏,在栈里面的一个引用指向堆里面的一个对象,这个对象后期不再使用,但这个对象始终和GCRoots有过关联,导致这个对象不能被回收(要及时把指针断掉)。
8内存溢出,对象太多了。
方法区内部结构
1方法区主要存储 类型信息、常量、静态变量、即时编译器编译后的代码缓存、域信息(属性)等。类型信息、字段、方法、常量和即时编译器的代码缓存在方法区,但字符串常量池、静态变量仍在堆。
2全局常量(static-final)编译的时候就写进方法区了
3运行时常量池(constant pool)(方法区的一部分)!(字节码文件里的是常量池)常量池里包含堆字面量、类型、域和方法的符号引用,这些数据很大不能直接放入字节码文件中,于是放到常量池,字节码文件里存的是相关引用。jvm从常量池里的表找到要执行的类、方法名、参数信息等。
4只有hotspot才有永久代,使用元空间的好处是,大小仅受本地内存限制(GC会少一些)。永久代设置空间很难确定,并且很难调优,这就是永久代被元空间替代的原因。
5、StringTable放入堆空间,之前在永久代回收效率低(在full gc的时候才触发),这样会导致内存不足,在堆中可以及时回收。full gc是老年代空间不足,永久代不足才会触发。
6、private static byte[] = new byte[12];静态引用的对象实体(new xxx)始终在堆空间,变量 arr引用名jdk8在堆空间
方法区的垃圾回收(常量池中废弃的常量和不使用的类型)
1字面量--文本字符串、声明为final的常量;符号引用--类和接口全限定名、字段名称描述符和方法名称描述符。
2回收原则(hotspot)--常量没有地方引用就回收。
3对于类的回收:(同时满足)