• JVM内存和垃圾回收-08.方法区


    1.栈、堆、方法区的交互关系

    首先大致回顾下内存区域的整体结构以及可能出现的异常:

    在这里插入图片描述

    对于语句Person person = new Person();,Person的class文件存储在方法区中,对象的引用person存放在栈中,new Person()后产生的对象存储在堆中

    在这里插入图片描述


    2.方法区的理解

    • 它是每个线程共享的内存区域
    • 在JVM启动时创建,且物理内存空间可以不连续
    • 和堆一样可以选择固定大小,也可扩展
    • 关闭JVM就会释放方法区的内存
    • 定义了太多的类会导致方法区溢出(比如Tomcat上部署了多个项目,每个项目需要使用反射创建类)
    • JDK7之前把方法区称为永久代;JDK8开始使用元空间取代永久代(元空间使用本地内存)

    3.方法区的内部结构

    方法区用于存储类型信息、运行时常量池、静态变量、即时编译器编译后的代码缓存等

    • 类型信息:包括类、接口、枚举、注解的信息
      • 类型的完整名称(包名.类名)
      • 直接父类的完整名称
      • 类的修饰符(public、final等)
      • 直接接口的列表
    • 域信息:即类中的属性
      • 域名称
      • 域类型
      • 域修饰符
    • 方法信息:
      • 方法名称
      • 返回类型
      • 方法的修饰符
      • 方法的字节码
      • 异常表

    对于类中使用final static修饰的属性,在链接的准备阶段就被赋予值,而一般的属性需要在初始化阶段才会被赋予值(该值是在代码中显示给定的值,即显示初始化)


    4.运行时常量池和常量池

    4.1 常量池

    • 源文件的类、接口编译后产生一个class文件,class文件需要数据的支持,该数据并不会直接存储在class文件中(常量池还是在class文件中,只不过不是直接在每一行字节码后使用常量,而是使用一个引用,如图中的#3),而是存储到常量池

    在这里插入图片描述

    在这里插入图片描述

    • 常量池可以视为一张表,JVM根据该表找到要执行的类名、参数类型、字面量等类型

    4.2 运行时常量池

    • 常量池是class文件的一部分,而运行时常量池是方法区的一部分
    • 常量池存储编译器生成的各种字面量和符号引用,该部分内容在类加载后存储在运行时常量池中
    • 动态性:运行时常量池除了常量池中在编译期已确定的数值字面量,还包括运行期解析后才能获得的方法或字段引用(如执行"psj".intern()时,如果在常量池中没有psj时,就会在运行时常量池中创建)
    • 也存在OOM异常

    5.方法区的演变*

    下面图中浅绿色部分表示JVM内存

    • JDK6:静态变量存放在永久代上

    在这里插入图片描述

    • JDK7:字符串常量池和静态变量从永久代移到堆中

    在这里插入图片描述

    • JDK8:无永久代,使用元空间替代,且元空间使用本地内存而不是JVM的内存

    在这里插入图片描述

    1.为什么使用元空间替换永久代?

    • 为永久代设置空间大小很难确定。元空间不在JVM中而在本地内存,所以它的大小受本地内存的限制,本地内存很少出现Full GC
    • 对永久代的调优十分困难

    2.StringTable为什么要调整?永久代GC效率低(在Full GC的时候才会触发,即老年代内存或永久代内存不足时),导致StringTable回收效率不高,而在开发中会使用到大量字符串,很容易导致永久代内存不足。堆中会及时回收内存

    3.静态引用对应的对象实体始终在堆空间中,而根据不同的JDK版本,由于静态变量存放的位置不同,该静态变量的引用可能在永久代中,也可能在堆中

    static byte[] arr = new byte[1024*1024*100];
    // arr根据JDK版本不同会存在不同的位置,而byte数组始终在堆中
    
    • 1
    • 2

    6.总结

    在这里插入图片描述

    为什么要分为新生代和老年代?为什么要有Survivor区?

    https://blog.csdn.net/u013126379/article/details/115590570


  • 相关阅读:
    jsp+ajax+json练习(表单数据检测)
    【夜莺监控方案】09-监控服务主机存活和服务端口(ICMP/TCP/HTTP)(prometheuse+n9e+blackbox_exporter)
    JVM之VisualVM工具的使用
    Spring bean 的生命周期(总结)
    计算机视觉与深度学习-循环神经网络与注意力机制-Attention(注意力机制)-【北邮鲁鹏】
    基于.Net C# 通信开发-网络调试助手
    SQL:数据去重的三种方法
    Android面试题汇总(五)
    win7常见问题
    Java进阶之路——从初级程序员到架构师,从小工到专家
  • 原文地址:https://blog.csdn.net/qq_41398418/article/details/126156131