在jdk1.8之前叫方法区,1.8之后修改成方法区,不同点在于,方法区属于堆空间一部分,是有默认大小的,元空间利用的是宿主机的内存,是动态扩展的
方法区存放的信息有哪些
1.class文件的基本信息,包括类,接口,枚举,注解,
2.运行时常量池(String常量池从1.7之后放入堆中)
3.JIT代码机器指令缓存
类的基本信息包括
1.实现的是哪个父类,实现的哪些接口,哪个类加载器加载的
2.域的信息,即属性的信息,包括类型,public 还是private等信息
3.方法信息,方法的实现,方法的返回值,方法参数等信息
运行时常量池
编译class 文件池中有常量池,对应的是记录该类用到的字面量,引用,和方法调用,我们称为静态常量池
作用是:一个类有父类和实现了很多接口,调用了很多方法,不能全部将这些类都写入到class文件中,所以需要记录符号引用
运行时常量池,是类加载器在加载的过程中,将class的静态常量池加载到方法区/元空间里面,不同的需要将符号引用,转化成实际引用,可以动态扩展,比如String.intren()方法就是手动将字符串put到字符串常量池中
为什么把方法区从jvm内存里拿出来使用元空间
1.方法区是存放类信息的,可能会动态的加载很多类,动态代理对象,调优会很困难,设置小了会发生OOM
设置大了,会出现浪费内存情况,总结一句就是调优困难.GC困难,因为判断类信息是否可回收很困难,比较消耗效率
2.但是字符串常量池和静态变量还是存放在堆内存中
为什么jdk7中将String常量池放入堆中
方法区垃圾回收频率低下,回收困难