当前位置: 首页 > news >正文

Hotspot源码解析-第十九章-ClassLoaderData、符号表、字符串表的初始化

第十九章-ClassLoaderData初始化

讲解本章先从一张图开始
在这里插入图片描述

众所周知,Java类的相关信息都是存储在元空间中的,但是是怎么存储的,相信很多读者是不清楚的,这里就不得不涉及到ClassLoaderDataGraph、classLoader、classLoaderData(简称CLD)和Klass的概念及他们四者的关系,这里简单描述下他们的概念,具体细节放到类加载器那一张来讲解。

InstanceKlass(继承自Klass):每个被加载的类在虚拟机中的表示为一个InstanceKlass

ClassLoaderData:类加载器加载类后,存储数据的对象,也就是说被加载的类最终都存储在ClassLoaderData指向的地方,一个CLD可以存入很多被加载的类InstanceKlass,多个InstanceKlass之间通过链表形式存储,且链表头永远是最新加载的类

ClassLoader:类加载器,每个ClassLoader都有一个CLD

ClassLoaderDataGraph:这是CLD的总入口,把所有CLD通过链表管理起来

19.1 根加载器CLD的创建

19.1.1 universe.cpp

19.1.1.1 ClassLoaderData::init_null_class_loader_data
static void init_null_class_loader_data() {// 验证重复初始化assert(_the_null_class_loader_data == NULL, "cannot initialize twice");assert(ClassLoaderDataGraph::_head == NULL, "cannot initialize twice");// 创建ClassLoaderData对象,第一个加载器的参数是NULL,因为在Java中,没有对根加载器的实现,这个是由虚拟机自身来实现加载的,所以相对Java,这是一个NULL,实现看`章节19.1.2`_the_null_class_loader_data = new ClassLoaderData((oop)NULL, false, Dependencies());// 创建完后,赋值给ClassLoaderDataGraph::_head,表示第一个CLDClassLoaderDataGraph::_head = _the_null_class_loader_data;assert(_the_null_class_loader_data->is_the_null_class_loader_data(), "Must be");if (DumpSharedSpaces) { // 不涉及多Java进程共享,这一步不会走_the_null_class_loader_data->initialize_shared_metaspaces();}}

19.1.2 classLoaderData.cpp

19.1.2.1 ClassLoaderData构造函数

发现这个构造函数,啥也没做,就是对字段赋初始值

ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :_class_loader(h_class_loader()),_is_anonymous(is_anonymous),// An anonymous class loader data doesn't have anything to keep// it from being unloaded during parsing of the anonymous class.// The null-class-loader should always be kept alive._keep_alive(is_anonymous || h_class_loader.is_null()),_metaspace(NULL), _unloading(false), _klasses(NULL),_claimed(0), _jmethod_ids(NULL), _handles(), _deallocate_list(NULL),_next(NULL), _dependencies(dependencies),_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) {JFR_ONLY(INIT_ID(this);)
}

19.2 符号表和字符串表

先了解下什么是符号表,什么是字符串表?

SymbolTable(符号表):符号是指字节码中产生的各种元数据的utf-8字符表示,所以符号表就是用来存放这些utf-8字符的

StringTable(字符串表):就是存放Java中String对象的,把StringTable表中的数据都可以想像成与Java中String对应

先这么理解吧,在类加载器那一章节会更细致的讲这两个概念。

以下是函数的部分内容,该函数是universe.cpp->universe_init()

// 创建符号表,把它想像成java里的HashMap
SymbolTable::create_table();
// 创建字符串表,把它想像成java里的HashMap
StringTable::create_table();
// 创建包信息表,也可以想像成一个HashMap,包信息用到的时候再讲
ClassLoader::create_package_info_table();SymbolTable类的定义:// 模板类,key为Symbol,value为mtSymbolclass SymbolTable : public RehashableHashtable<Symbol*, mtSymbol> 
StringTable类的定义:// 模板类,key为oop,value为mtSymbolclass StringTable : public RehashableHashtable<oop, mtSymbol> SymbolTable:key是Symbol,Symbol可以理解为utf8编码的字符信息
SymbolTable:value是mtSymbol,这是一个枚举值,仅仅表示内存的类型解释,不起实际作用StringTable:key是oop,oop可以理解为指向Java对象的地址(实际上存放的就是Java的String对象的地址)
StringTable:value是mtSymbol,这是一个枚举值,仅仅表示内存的类型解释,不起实际作用

两个表的创建过程都非常简单,但是符号表SymbolTable的创建要复杂些,增加了initialize_symbols初始化符号的操作,代码如下:

static void create_table() {assert(_the_table == NULL, "One symbol table allowed.");_the_table = new SymbolTable();// 预先创建并分配存放符号的内存chunk,symbol_alloc_arena_size = 360Kinitialize_symbols(symbol_alloc_arena_size);}void SymbolTable::initialize_symbols(int arena_alloc_size) {// Initialize the arena for global symbols, size passed in depends on CDS.if (arena_alloc_size == 0) {_arena = new (mtSymbol) Arena(mtSymbol);} else {// 创建一个Arena对象,细节看`章节19.2.1`_arena = new (mtSymbol) Arena(mtSymbol, arena_alloc_size);}
}

19.2.1 allocation.cpp

19.2.1.1 Arena构造函数

在JVM运行过程中,会产生大量的符号,为了效率在存储时不可能来一个分配一个,所以需要提前划出一片区域chunk来存储,如果一块chunk不够了,再创建一块,依此类推,Arena就是管理这些chunk的类对象,各chunk之间以链表的形式关联,整个JVM中对内存的管理中,大量使用链表这一数据结构来处理。顺便描述下Arena的几个字段的含义

Chunk *_first; // 第一块 chunk
Chunk *_chunk; // 前在用的 chunk
char *_hwm, *_max; // 当前在用的 chunk 起始点和限制点
size_t _size_in_bytes; // Arena的总大小(所有chunk大小相加)

Arena::Arena(MEMFLAGS flag, size_t init_size) : _flags(flag), _size_in_bytes(0)  {size_t round_size = (sizeof (char *)) - 1;init_size = (init_size+round_size) & ~round_size;// 主要看这里,创建了一个init_size大小的chunk块_first = _chunk = new (AllocFailStrategy::EXIT_OOM, init_size) Chunk(init_size);_hwm = _chunk->bottom();      // 保存 hwm, max,分别指向chunk块可操作的起始点和限制点_max = _chunk->top();MemTracker::record_new_arena(flag);set_size_in_bytes(init_size);
}

相关文章:

Hotspot源码解析-第十九章-ClassLoaderData、符号表、字符串表的初始化

第十九章-ClassLoaderData初始化 讲解本章先从一张图开始 众所周知&#xff0c;Java类的相关信息都是存储在元空间中的&#xff0c;但是是怎么存储的&#xff0c;相信很多读者是不清楚的&#xff0c;这里就不得不涉及到ClassLoaderDataGraph、classLoader、classLoaderData&…...

impala元数据自动刷新

一.操作步骤 进入CM界面 > Hive > 配置 > 搜索 启用数据库中的存储通知(英文界面搜索&#xff1a;Enable Stored Notifications in Database)&#xff0c;并且勾选&#xff0c;注意一定要勾选&#xff0c;配置后面的配置不生效。数据库通知的保留时间默认为2天&#…...

骑砍战团MOD开发(35)-射击精度系统

一.射击精度 和CF等FPS射击类游戏一样,为了模拟实际射击过程中弓箭,子弹等投掷物的射击偏移,故设计精度系统控制不同武器不同兵种的使用武器能力,统称为游戏精度系统. 由于骑砍可以在马上进行射击,故引擎内部也内置了骑射技能点以便控制玩家在骑马过程中射击的能力. 武器精度:通…...

树莓派非常实用的程序-3 vcdbg

vcdbg 是一个应用程序&#xff0c;用于帮助从在ARM上运行的Linux调试VideoCore GPU。它需要以根用户身份运行。此应用程序主要用于Raspberry Pi工程师&#xff0c;尽管有一些命令一般用户可能会发现有用。 sudo vcdbg help 将给出可用命令的列表。 NOTE 仅列出了最终用户使用…...

jmeter分布式服务搭建

目录 一、环境准备 二、 安装包下载 三 、安装jdk 四 、控制机安装 4.1 解压压缩包 4.2 修改 bin/jmeter.properties 4.3 修改 bin/system.properties 五、执行机安装 5.1 解压安装包 5.2 修改 bin/jmeter.properties 5.3 修改 bin/system.properties 5.4 启动执行机 …...

vue中el-radio无法默认选中

页面上不生效&#xff0c;默认什么都不选中 <el-radio-group v-model"queryParams.videoUrlType"><el-radio :label"1">本地上传</el-radio><el-radio :label"2">外部链接</el-radio> </el-radio-group>da…...

分布式I/O应用于智慧停车场的方案介绍

客户案例背景 目前车位检测技术有磁电技术、超声波技术、红外线技术、图像识别车位技术。考虑到例如电磁干扰、信号干扰等的环境因素影响&#xff0c;通常会采用组合使用的方式进行&#xff0c;如采用不同的传感器、应用不同的协议等&#xff0c;以便提高车位检测的准确性和实时…...

node后端+vue前端实现接口请求时携带authorization验证

node后端vue前端实现接口请求时携带authorization验证 我们在写web项目时&#xff0c;后端写好接口&#xff0c;前端想要调用后端接口时&#xff0c;除了登录注册页面&#xff0c;所有的请求都需要携带authorization&#xff0c;这样是为了避免随意通过接口调取数据的现象发生…...

SourceTree管理git

SourceTree管理git...

【数模百科】一篇文章讲清楚灰色预测模型GM(1,1)附python代码

本篇文章摘录自GM(1,1) - 数模百科 &#xff0c;如果想了解更多有关灰色预测模型的信息&#xff0c;请移步 灰色预测模型 - 数模百科 首先&#xff0c;“灰色”这个词在这里不是指颜色&#xff0c;而是形容一种信息状态&#xff0c;介于黑&#xff08;信息全无&#xff09;和白…...

openssl3.2 - 官方demo学习 - mac - hmac-sha512.c

文章目录 openssl3.2 - 官方demo学习 - mac - hmac-sha512.c概述笔记END openssl3.2 - 官方demo学习 - mac - hmac-sha512.c 概述 MAC算法为HMAC, 设置参数(摘要算法为SHA3-512), 用key初始化, 对明文做MAC数据. 笔记 /*! \file hmac-sha512.c \note openssl3.2 - 官方demo…...

pycharm的使用技巧

1.新建文件时,自动生成代码 settings->editor->file and code templates,选择python script ${NAME} 文件名 ${DATE} 日期 2.自动补齐自定义段落 settings->editor->live templates,在右侧点击+号,添加自定义的内容 完成之后,在下方勾选python 3.修改注释的…...

如何通过内网穿透实现公网访问Portainer管理监控Docker容器

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风…...

Redis原理篇(Dict的收缩扩容机制和渐进式rehash)

Dict&#xff08;即字典&#xff09; Redis是一种键值型数据库&#xff0c;其中键与值的映射关系就是Dict实现的。 Dict通过三部分组成&#xff1a;哈希表&#xff08;DictHashTable&#xff09;&#xff0c;哈希节点(DictEntry)&#xff0c;字典&#xff08;Dict&#xff09…...

Microsoft Remote Desktop for Mac 中文正式版下载 微软远程连接软件

Microsoft Remote Desktop 是一款专为 Mac 用户设计的远程桌面工具&#xff0c;它可以帮助用户通过网络连接到其他计算机&#xff0c;实现远程控制和操作。 软件下载&#xff1a;Microsoft Remote Desktop for Mac 中文正式版下载 该工具支持多种远程连接协议&#xff0c;包括 …...

解读Vue的原型及原型链

在 JavaScript 中&#xff0c;每个对象都有一个关联的原型&#xff08;prototype&#xff09;。原型是一个对象&#xff0c;其他对象可以通过原型实现属性和方法的继承。原型链是一种由对象组成的链式结构&#xff0c;它通过原型的引用连接了一系列对象&#xff0c;形成了一种继…...

拓扑排序(优先队列)queue、C++

N个小朋友&#xff0c;编号 1∼N&#xff0c;要排成一队。在安排每个人的顺序时&#xff0c;有 M 个要求&#xff0c;每个要求包含两个整数 a,b&#xff0c;表示小朋友 a 要排在小朋友 b 的前面。 请你找出符合所有要求的排队顺序。 输入格式 第一行包含整数 N,M。接下来 M 行…...

【Spring】SpringBoot 统一功能处理

文章目录 前言1. 拦截器1.1 什么是拦截器1.2 拦截器的使用1.2.1 自定义拦截器1.2.2 注册配置拦截器 1.3 拦截器详解1.3.1 拦截路径1.3.2 拦截器执行流程1.3.3 适配器模式 2. 统一数据返回格式3. 统一异常处理 前言 在日常使用 Spring 框架进行开发的时候&#xff0c;对于一些板…...

拦截器HandlerInterceptor | springmvc系列

拦截器&#xff0c;通俗来来将&#xff0c;就是我们将访问某个路径的请求给拦截下来&#xff0c;然后可以对这个请求做一些操作 基本使用 创建拦截器类 让类实现HandlerInterceptor接口&#xff0c;重写接口中的三个方法。 Component //定义拦截器类&#xff0c;实现Handle…...

【SQL server】DML触发器监控数据库字段值改变

文章目录 前言DML触发器基本思路创建触发器固定字段触发示例完整示例代码变量声明查询新旧值插入数据到日志表效果视频动态字段触发示例完整代码示例触发器基本信息变量声明定义游标打开游标临时表创建循环处理字段...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...