JVM基础篇-方法区与运行时常量池

news2024/11/13 16:21:53

JVM基础篇-方法区与运行时常量池

方法区

在这里插入图片描述

Java 虚拟机有一个在所有 Java 虚拟机线程之间共享的方法区。方法区类似于传统语言的编译代码的存储区或者类似于操作系统进程中的“文本”段。它存储每个类的结构,例如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括类和实例初始化以及接口初始化中使用的特殊方法,方法区是在虚拟机启动时创建的。尽管方法区在逻辑上是堆的一部分,但简单的实现可以选择不进行垃圾收集或压缩它。本规范不强制要求方法区的位置或用于管理编译代码的策略。方法区可以是固定大小的,或者可以根据计算的需要来扩展,并且如果不需要更大的方法区,则可以收缩。方法区的内存不需要是连续的。

Java虚拟机实现可以为程序员或用户提供对方法区的初始大小的控制,以及在方法区大小变化的情况下,对最大和最小方法区大小的控制。

如果方法区中的内存无法满足分配请求,Java 虚拟机将抛出一个OutOfMemoryError

参考文档

方法区jdk1.6实现

在这里插入图片描述

  • 在jdk1.6中方法区在jvm中是通过永久代实现的,包含运行时常量池、类字节码信息、类加载器
方法区jdk1.8实现

在这里插入图片描述

  • jdk1.8中方法区实现改为元空间实现,而元空间占用的内存不再是JVM内存,而是本地内存,需要注意的是字符串常量池StringTable被移至堆内存中

方法区内存溢出

1.8 以前会导致永久代内存溢出

  • 异常类型java.lang.OutOfMemoryError: PermGen space

  • 设置永久代内存大小:

    -XX:MaxPermSize=8m
    

1.8 之后会导致元空间内存溢出

  • 异常类型java.lang.OutOfMemoryError: Metaspace

  • 设置元空间内存大小

    -XX:MaxMetaspaceSize=8m
    
示例代码
package com.vmware.stack;

import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;

/**
 * @apiNote 演示元空间内存溢出
 * -XX:MaxMetaspaceSize=8m 设置元空间大小  1.8之后
 * -XX:MaxPermSize=8m 设置永久代大小       1.8之前
 */
public class Demo8 extends ClassLoader {
    public static void main(String[] args) {
        int j = 0;
        try {
            Demo8 test = new Demo8();
            for (int i = 0; i < 10000; i++,j++) {
                //ClassWriter 作用是生成类的二进制字节码
                ClassWriter cw = new ClassWriter(0);
                //版本号  public  类名   包名   父类    接口
                cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);
                //返回byte[]类二进制字节码
                byte[] code = cw.toByteArray();
                //执行类加载
                test.defineClass("Class" + i, code, 0, code.length);//Class对象
            }
        }finally {
            System.out.println(j);
        }
    }
}
场景
  • spring
  • mybatis

这些框架在运行期间会生成大量的代理类,可能会引起内存不足

二进制字节码的组成
  • 类基本信息
  • 常量池
  • 类方法定义,包含了虚拟机指令
package com.vmware.stack;

public class Demo9 {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

反编译:javap -v xxx.class

-------------------------------------------------------------------类基本信息
Classfile /home/ubuntu/Desktop/worker/jvm/target/classes/com/vmware/stack/Demo9.class
  Last modified Aug 1, 2023; size 552 bytes
  SHA-256 checksum b17f11f1b24fba016d8e0cdfb28ccef1cb9c7000e23c67e11b29fb068b9556b0
  Compiled from "Demo9.java"
public class com.vmware.stack.Demo9
  minor version: 0
  major version: 52
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #5                          // com/vmware/stack/Demo9
  super_class: #6                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 1
--------------------------------------------------------------------常量池
Constant pool:
//#开头的称为符号地址
   #1 = Methodref          #6.#20         // java/lang/Object."<init>":()V
   #2 = Fieldref           #21.#22        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #23            // hello world
   #4 = Methodref          #24.#25        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #26            // com/vmware/stack/Demo9
   #6 = Class              #27            // java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/vmware/stack/Demo9;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               args
  #17 = Utf8               [Ljava/lang/String;
  #18 = Utf8               SourceFile
  #19 = Utf8               Demo9.java
  #20 = NameAndType        #7:#8          // "<init>":()V
  #21 = Class              #28            // java/lang/System
  #22 = NameAndType        #29:#30        // out:Ljava/io/PrintStream;
  #23 = Utf8               hello world
  #24 = Class              #31            // java/io/PrintStream
  #25 = NameAndType        #32:#33        // println:(Ljava/lang/String;)V
  #26 = Utf8               com/vmware/stack/Demo9
  #27 = Utf8               java/lang/Object
  #28 = Utf8               java/lang/System
  #29 = Utf8               out
  #30 = Utf8               Ljava/io/PrintStream;
  #31 = Utf8               java/io/PrintStream
  #32 = Utf8               println
  #33 = Utf8               (Ljava/lang/String;)V
---------------------------------------------------------------------类方法定义
{
  public com.vmware.stack.Demo9();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/vmware/stack/Demo9;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
      ------------------------------------------------------------虚拟机指令
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String hello world
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 5: 0
        line 6: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
}
SourceFile: "Demo9.java"

运行时常量池

  • 常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
  • 运行时常量池,常量池是 *.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/824598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图像处理库(Opencv, Matplotlib, PIL)以及三者之间的转换

文章目录 1. Opencv2. Matplotlib3. PIL4. 三者的区别和相互转换5. Torchvision 中的相关转换库5.1 ToPILImage([mode])5.2 ToTensor5.3 PILToTensor 1. Opencv opencv的基本图像类型可以和numpy数组相互转化&#xff0c;因此可以直接调用torch.from_numpy(img) 将图像转换成t…

Sql server 2005 卸载之后重新安装

Sql server 2005 卸载之后重新安装 Sql sercer 2005在重新安装之前先要进行卸载操作&#xff0c;由于Sql sercer 2005组件都是分散的&#xff0c;所以卸载时要找到对应的位置一个一个卸载&#xff0c;不卸载干净的情况下再次安装时会出现很多问题&#xff0c;导致安装失败。这…

KubeSphere部署芋道源码ruoyi-vue-pro

KubeSphere环境准备 新建企业空间 新建项目 创建harbor镜像服务信息 新建DevOps 项目 创建git,harbor,kubeconfig凭证 中间件部署 MySQL8部署redis6部署 后端部署 修改pom.xml <!-- pom.xml添加内容&#xff1a;--> <profiles><!-- 本地环境 --><pro…

《当今奇人周兴和》励志小说连载之三 ● 饥饿寒冷童年梦

饥饿寒冷童年梦 Hungry and cold childhood 兴和至今也记得&#xff0c;这年冬天特别冷。 Xinghe still remembers that the winter was particularly cold in that year. 那一天&#xff0c;放了学的小兴和背着书兜&#xff0c;又冷又饿地从毛公乡小学出来&#xff0c;艰难…

渠道控价的常见方法

品牌渠道一般分为线上和线下&#xff0c;现在常见要治理的渠道一般指的是线上&#xff0c;因为线上渠道数据变化快&#xff0c;价格波动也很大&#xff0c;促销信息有很多&#xff0c;如果遇到大促&#xff0c;涉及的价格变化将会更明显&#xff0c;所以线上渠道是非常值得控价…

OA办公自动化系统设计与实现(论文+源码)_kaic

摘要 随着信息化建设的日益深入&#xff0c;无论是政府还是企事业单位&#xff0c;部门之间的信息沟通与协调工作越来越重要。人们迫切需要一个能充分利用网络优势&#xff0c;并可以管理企业的各种重要信息的软件平台&#xff0c;利用该平台快速建立自己的信息网络和办公管理系…

华为PMS API client token auth failed

对接华为pms时出现问题&#xff0c;提示华为PMS API client token auth failed 主要是权限的问题&#xff0c;创建项目的时候选择N/A

u盘数据不知道什么时候全没了怎么恢复

案例&#xff1a;“你好&#xff0c;我发现我的U盘上的所有数据都不知何时消失了&#xff0c;我之前保存了许多重要的文件和照片&#xff0c;U盘数据不知道什么时候全没了怎么恢复&#xff1f;大神你知道么” 随着U盘的广泛应用&#xff0c;数据丢失问题也日益突出。很多人发现…

【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 4

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

chrome扩展在popup、background、content之间通信解决传输文件问题

文章目录 背景介绍案例介绍代码示例popup页面&#xff0c;上传文件页面popup页面&#xff0c;js上传代码&#xff0c;file文件转base64background监听消息&#xff0c;base64转file文件&#xff0c;axios上传 附-转base64后直接下载 背景介绍 示例扩展API版本MV2。 以弹…

Linux下安装配置Redis

文章目录 安装依赖库上传安装包并解压 启动默认启动指定配置启动开机自启 安装 依赖库 Redis是基于C语言编写的&#xff0c;因此首先需要安装Redis所需要的gcc依赖&#xff1a; yum install -y gcc tcl上传安装包并解压 将Redis安装包上传到服务器的任意目录&#xff0c;例…

使用WebMvcConfigurationSupport后导致原来返回的json数据变为了xml的解决方法

问题 未使用WebMvcConfigurationSupport拦截时返回的数据都是JSON格式&#xff0c;使用WebMvcConfigurationSupport做拦截后数据的返回变为了XML的格式。 原因 在Spring框架中&#xff0c;WebMvcConfigurationSupport 是一个类&#xff0c;它可以用于自定义Spring MVC的配置…

【word密码】如何解密word密码?

Word文档常见的两种加密方式&#xff0c;打开密码和限制编辑&#xff0c;这两种密码对word文档加密&#xff0c;今天我们来讲一下这三种加密如何解密 解密一&#xff1a;打开密码 设置了打开密码的word文件&#xff0c;想要解密&#xff0c;我们需要先输入密码进入到文件当中…

IO进程线程第四天(8.1)opendir,closedir,readdir

作业1&#xff1a; 从终端获取一个文件的路径以及名字。 若该文件是目录文件&#xff0c;则将该文件下的所有文件的属性显示到终端&#xff0c;类似ls -l该文件夹 若该文件不是目录文件&#xff0c;则显示该文件的属性到终端上&#xff0c;类似ls -l这单个文件 #include<…

华为OD机试真题 JavaScript 实现【箱子之形摆放】【2023 B卷 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、JavaScript算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例…

【Uniapp 中实现微信登录】

要在 Uniapp 中实现微信登录&#xff0c;需要完成以下步骤&#xff1a; 在微信开放平台注册一个应用&#xff0c;并获取到该应用的 AppID 和 AppSecret。 在 manifest.json 中点击App模块配置。勾选微信登录模块&#xff0c;填入该应用的 AppID 在代码中调用 uni.login 方法&…

学习记录——EGE-UNet、CFNet

EGE-UNet: an Efficient Group Enhanced UNet for skin lesion segmentation 上海交大 2023 MICCAI 基于 U-Net 进行魔改&#xff0c;用于解决医学图像&#xff08;尤其是皮肤病变&#xff09;分割中面临的问题。由于它是针对移动健康应用开发的&#xff0c;解决了当前许多模型…

docker下载镜像慢

下载镜像的方法 手动下载&#xff0c;然后再打开 此方法有局限&#xff0c;因为不是所有的镜像地址都支持http访问。 方法是打开此镜像市场网站&#xff0c;搜索自己想要的镜像&#xff0c;然后点击下载即可。 Linux一般是下载一个压缩包&#xff0c;解压之后docker load就可…

用于医学图像分类的双引导的扩散网络

文章目录 DiffMIC: Dual-Guidance Diffusion Network for Medical Image Classification摘要本文方法实验结果 DiffMIC: Dual-Guidance Diffusion Network for Medical Image Classification 摘要 近年来&#xff0c;扩散概率模型在生成图像建模中表现出了显著的性能&#xf…

【update】自动更新设计小记

前情纪要 老项目的一个更新迭代实例方式处理&#xff0c;从功能梳理&#xff0c;待流程设计,…了解功能&#xff0c;时序图&#xff0c;流程图记录 关系图梳理 流程图设计