【JVM基础05】——组成-能不能解释一下方法区?

目录

  • [1- 引言:方法区概述](#1- 引言:方法区概述)
    • [1-1 方法区是什么?(What)](#1-1 方法区是什么?(What))
    • [1-2 为什么用方法区?方法区的作用 (Why)](#1-2 为什么用方法区?方法区的作用 (Why))
  • [2- ⭐核心:详解方法区(How)](#2- ⭐核心:详解方法区(How))
    • [2-1 能不能解释一下方法区?](#2-1 能不能解释一下方法区?)
    • [2-2 元空间内存溢出问题](#2-2 元空间内存溢出问题)
    • [2-3 什么是常量池?](#2-3 什么是常量池?)
    • [2-4 运行时常量池](#2-4 运行时常量池)
  • [3- 小结:](#3- 小结:)
    • [3-1 什么是方法区?方法区的作用?](#3-1 什么是方法区?方法区的作用?)
    • [3-2 介绍一下运行时常量池?](#3-2 介绍一下运行时常量池?)

1- 引言:方法区概述

1-1 方法区是什么?(What)

  • 方法区是 Java 虚拟机中的一个运行时数据区,它是各个线程共享的内存区域,主要用于存储类的信息和运行时常量池。
  • 方法区在 Java 虚拟机启动时创建,在虚拟机关闭时释放。具体存储内容包括类的结构、方法、字段以及运行时常量池的信息。
    • 在 JDK 8之前,方法区存储在堆中的永久代区域
    • 在 JDK 8之后,永久代被移除,改为元空间,使用的是操作系统的本地内存

1-2 为什么用方法区?方法区的作用 (Why)

  • ① 存储类信息:方法区存储所有被加载类的结构信息,包括类名、访问修饰符、字段描述、方法描述等。这些信息在类加载时会被读取并存储到方法区,以便于虚拟机执行相应的操作。
  • ② 存储运行时常量池:运行时常量池是方法区的重要组成部分,包含了编译期间生成的各种字面量和符号引用。当类被加载时,常量池的信息会被加载到运行时常量池,并将符号地址转换为真实的内存地址,以便在程序运行时进行快速查找和执行。
  • ③ 支持类加载和卸载:方法区在类加载时创建,在类卸载时释放存储空间。它的存在使得Java虚拟机可以动态加载和卸载类,从而支持Java的动态性和扩展性。

2- ⭐核心:详解方法区(How)

2-1 能不能解释一下方法区?

  • 方法区(Method Area) 是各个线程 共享的内存区域
  • 主要存储类的信息、运行时常量池
  • 虚拟机启动的时候创建,关闭虚拟机时释放
  • 如果方法区域中的内存无法满足分配请求,则会抛出OutOfMemoryError:Metaspace

2-2 元空间内存溢出问题

  • 以下代码演示了通过动态生成和加载类来导致Java虚拟机的元空间(Metaspace)内存溢出(java.lang.OutOfMemoryError: Metaspace)的情况。

在没有设置元空间大小上限的情况下

  • 以下代码的执行是没有错误的

**如果设置了 **-XX:MaxMetaspaceSize=8m

  • 此时会抛出 java.lang.OutOfMemoryError: Metaspace异常
java 复制代码
/**
 * 演示元空间内存溢出 java.lang.OutOfMemoryError: Metaspace
 * -XX:MaxMetaspaceSize=8m
 */
public class MetaspaceDemo extends ClassLoader { // 可以用来加载类的二进制字节码
    public static void main(String[] args) {
        MetaspaceDemo test = new MetaspaceDemo();
        for (int i = 0; i < 10000; i++) {
            // ClassWriter 作用是生成类的二进制字节码
            ClassWriter cw = new ClassWriter(0);
            // 版本号,public,类名,包名,父类,接口
            cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);
            byte[] code = cw.toByteArray();
            // 执行类的加载
            test.defineClass("Class" + i, code, 0, code.length); // Class 对象
        }
    }
}

2-3 什么是常量池?

  • 常量池可以看做是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息。
  • 字符串常量池(String Constant Pool)是Java虚拟机中的一个特殊内存区域,用于存储字符串字面量。
  • 一个Java方法的机器指令想要执行,则需要他要去查表,翻译到常量池中去找到对应的地址进行翻译,然后最终才能去执行当前的指令。

2-4 运行时常量池

  • 常量池是 .class 文件中的,当该类被加载,它的常量池信息就会 放入运行时常量池,并把里面的 符号地址变为真实地址*

3- 小结:

3-1 什么是方法区?方法区的作用?


3-2 介绍一下运行时常量池?

相关推荐
晚安code32 分钟前
JVM 内存结构入门:程序计数器、虚拟机栈、本地方法栈与堆的溢出诊断
java·jvm
老三牛擦2 小时前
多平台上架
jvm
自强的小白3 小时前
jvm面试(Gc)
服务器·jvm·面试
晚安code4 小时前
JVM 垃圾回收全流程拆解:可达性分析、四种算法与五种收集器选型
jvm
用户094248568034 小时前
第20章:JVM G1 GC原理、日志与调优实战
java·jvm
艾莉丝努力练剑7 小时前
【AI大模型接入SDK】ChatSDK 集成测试概述
jvm·c++·人工智能·学习·面试·集成测试·sdk
Joe_Wang57 小时前
【从0到1学习JVM · 14】堆内存各区域分工与Xms和Xmx设为一样的真相
java·jvm·学习·垃圾回收
HwJack207 小时前
【HarmonyOS开发小实践】HarmonyOS GC 引用计数 vs 对象追踪,三种回收算法
jvm·算法·harmonyos
_upupup20 小时前
异常(C++)
java·开发语言·jvm
老三牛擦1 天前
掌握数据结构及算法、计算机组成原理、操作系统、计算机网络和软件工程基础知识,践行Scrum敏捷开发理念
jvm