💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
### Method Area\(Non-Heap\)方法区 方法区是所有线程共享的内存区域,用于存储已加载的类信息(Klass元数据)、常量、静态变量、即时编译器编译后的代码等数据; 方法区包含运行时常量池,Class 文件的各种字面量和符号引用,在类加载后会存入到运行时常量池中。直接引用也会存储在运行时常量池。除了类加载阶段,运行时常量也可以动态加入,比如String的 intern\(\)方法; 其实在很久以前,是不存在永久代的。当时永久代与年老代都存放在一起,里面包含了JAVA类的实例信息以及类信息。但是后来发现,对于类信息的卸载几乎很少发生,因此便将二者分离开来 #### 数据对象 * 已加载类信息 * 该类型的全限定名如java.io.FileOutputStream * 该类型的直接超类的全限定名如java.io.OutputStream * 该类型是类类型还是接口类型 * 该类型的访问修饰符\(public、abstract、final\) * 任何直接超接口的全限定名的有序列表如java.io.Closeable, java.io.Flushable * 指向Class类的引用 * 字段和方法数据 * 字段信息:对类型中声明的每个字段 * 方法信息 * 构造函数和普通方法的字节码内容 * 接口初始化时需要用到的特殊方法 * 运行时常量池:类和接口的全限定名、字段的名称和描述符、基本数据类型的直接数值(final)等 * 静态变量:静态变量而不是放在堆里面,所以静态属于类,不属于对象 * 即时编译器编译后的代码 * 指向ClassLoader类的引用 * 方法表:为了能快速定位到类型中的某个方法,JVM对每个装载的类型都会建立一个方法表,用于存储该类型对象可以调用的方法的直接引用,这些方法就包括从超类中继承来的而这张表与Java动态绑定机制的实现是密切相关的 ### JVM参数 PermSize:在Linux下JDK8默认大小为20.79M; #### 注意 * JDK1.7的HotSpot已经把放在永久代的字符串常量池移出 * JDK1.8已将PermGen从Heap中移除 * 特别说明:java类中所有public和protected的实例方法都采用动态绑定机制,所有私有方法、静态方法、构造器及初始化方法<clinit>都是采用静态绑定机制。而使用动态绑定机制的时候会用到方法表,静态绑定时并不会用到 #### 知识点 * 如果没有显式要求不对方法区进行内存回收,GC回收目标仅针对方法区中的常量池和类型卸载; * JAVA虚拟机规范对方法区的限制非常宽松,除了和JAVA堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集; 对于Perm事实上是Hotspot虚拟机的特定实现,HotSpot虚拟机把GC分代收集扩展至方法区,所以在HotSpot可以称它为永久代\(Permanent Generation\),对于其他虚拟机不存在永久代的概念; 由于Perm主要存储类信息,对于动态生成类的场景容易出现OOM;比如jsp页面比较多大的场景,容易出现永久代的OOM;