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);
}

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

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

相关文章

MIT 6s081 lab 5: xv6 lazy page allocation

Page faults Basic 通过page fault可以实现一系列的虚拟内存功能&#xff1a; lazy allocationcopy-on-write forkdemand pagingmemory mapped files 虚拟内存的两个主要的优点&#xff1a; 1、隔离性&#xff1a;每个应用程序拥有自己的地址空间&#xff0c;因此不可能修…

【Dart】=> [06] Dart初体验-类Class-构造函数-继承-mixin-异步编程-链式调用-泛型-异常

目录 能够定义并使用Dart的类类的定义构造函数私有属性和方法继承mixin异步编程FutureFuture链式调用async - awaitdynamic类型泛型异常 能够定义并使用Dart的类 Dart是一门面向对象的编程语言&#xff0c;所有的对象都是类的实例 通过类我们可以对数据和方法进行封装复用 学习…

(2023版)斯坦福CS231n学习笔记:DL与CV教程 (1) | 引言与知识基础

前言 &#x1f4da; 笔记专栏&#xff1a;斯坦福CS231N&#xff1a;面向视觉识别的卷积神经网络&#xff08;23&#xff09;&#x1f517; 课程链接&#xff1a;https://www.bilibili.com/video/BV1xV411R7i5&#x1f4bb; CS231n: 深度学习计算机视觉&#xff08;2017&#xf…

NLP论文阅读记录 - 2022 | WOS 用于摘要法律文本的有效深度学习方法

文章目录 前言0、论文摘要一、Introduction1.1目标问题 二.相关工作三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结 前言 Effective deep learning approaches for summarization of legal texts&#xff08;22&#x…

Linux -- Nginx服务基础

4.1Nginx服务基础 Nginx(发音为[engine x])专为性能优化而开发&#xff0c;其最知名的优点是它的稳定性和低系统资源消 耗&#xff0c;以及对HTTP并发连接的高处理能力&#xff08;单台物理服务器可支持30000~50000个并发请求&#xff09;&#xff0c;正因 为如此&#xff0c;…

vscode中关于python的一些常用配置

文章目录 python cv2 提示配置第一步 配置提示信息第二部 重启vs 可能还不行&#xff0c;那就重新安装以下opencv-python 配置pytest还是如上&#xff0c;将下入的位置打开编写测试用例 配置跨文件import在工作目录中新建一个.env文件输入内容如下打开.vscode中的setting.json …

目标识别跟踪模块Tofu3

Tofu系列提供了适应不同目标、不同速率的识别跟踪模块产品系列&#xff0c;主要包括Tofu3&#xff0c;4&#xff0c;5&#xff0c;S和其他零配件&#xff0c;可以适配BT.656,Cameralink&#xff0c;网络等不同接口和协议的热红外、可见光视频。 Tofu3 是多波段视频物体识别跟踪…

GL Logger和CANFDLog-OTL-128两款记录仪都是如何实现高效的报文录制的?

GL Logger是Vector推出的记录CAN/CAN FD、LIN、FlexRay和MOST数据通信的工具。以GL2400为例带着大家一步步地实现路试过程中通过整车OBD口进行CAN/CANFD报文的录制。 Step1 设备配置 设备配置即设备录制方式、录制内容、设备休眠唤醒策略等。 ▷ 打开Vector Logger Configurat…

UML-用例图

提示&#xff1a;用例图是软件建模的开始&#xff0c;软件建模中的其他图形都将以用例图为依据。用例图列举了系统所需要实现的所有功能&#xff0c;除了用于软件开发的需求分析阶段&#xff0c;也可用于软件的系统测试阶段。 UML-用例图 一、用例图的基础知识1.用例图的构成元…

使用numpy处理图片——滤镜

大纲 3维数组切分打平重组法深度切分法 3维数组堆叠 我们在用手机拍照片时&#xff0c;往往会对照片进行滤镜处理&#xff0c;从而让照片更加美观。本文我们将实现几种滤镜效果——去除所有像素中的某一种原色&#xff0c;形成只有红绿、红蓝和绿蓝原色的照片。 为了突出色彩丰…

定制服务器有什么优势优点?

定制服务器是指在根据用户的需求和业务特点&#xff0c;专门设计和制造的服务器。与标准服务器相比&#xff0c;定制服务器具有以下优势和优点&#xff1a; 更好的性能&#xff1a;定制服务器可以针对特定应用进行优化&#xff0c;从而提高服务器的性能。由于定制服务器不需要…

Win和Mac系统重置系统方法

注意&#xff1a;重置系统前&#xff0c;请备份好系统盘资料到其他盘符&#xff01;重置系统将会删除应用和系统设置&#xff0c;甚至用户文件&#xff0c;还原为出厂设置模式。 Windows重置系统操作方法。&#xff08;目前支持WIN8&#xff0c;WIN10&#xff0c;WIN11&#x…

Linux系统使用docker部署Geoserver(简单粗暴,复制即用)

1、拉取镜像 docker pull kartoza/geoserver:2.20.32、创建数据挂载目录 # 统一管理Docker容器的数据文件,geoserver mkdir -p /mydata/geoserver# 创建geoserver的挂载数据目录 mkdir -p /mydata/geoserver/data_dir# 创建geoserver的挂载数据目录&#xff0c;存放shp数据 m…

【数据库原理】(24)数据库安全性策略

数据库安全性是数据库管理系统&#xff08;DBMS&#xff09;中一个至关重要的方面。它指的是保护数据库免受非授权访问和恶意操作&#xff0c;包括数据泄露、修改、破坏等。 多层安全模型 在典型的计算机系统安全模型中&#xff0c;安全措施被设置在不同层级&#xff1a; 应用…

Unity ComputeShader 使用GPU快速计算复杂问题

Unity ComputeShader 使用GPU快速计算复杂问题 前言项目创建ComputeShader编写CompturShader创建Unity代码场景布置运行场景 参考 前言 遇到一个问题&#xff0c;需要大量的计算&#xff0c;在Unity中直接写会长时间的阻塞主线程&#xff0c;正好使用ComputeShader让GPU来帮我…

海格里斯HEGERLS仓储货架生产厂家|载荷1.5T运行速度1.7~2m/s的智能四向穿梭车系统

四向穿梭车立体库是近年来出现的一种智能型密集系统&#xff0c;通过使用四向穿梭车在货架的水平和纵向轨道上运行来搬运货物&#xff0c;一台四向穿梭车就能完成货物的搬运工作&#xff0c;大大提高了工作效率。同时配合提升机、自动化仓库管理系统(WMS)和仓库调度系统(WCS)&a…

使用WAF防御网络上的隐蔽威胁之SSRF攻击

服务器端请求伪造&#xff08;SSRF&#xff09;攻击是一种常见的网络安全威胁&#xff0c;它允许攻击者诱使服务器执行恶意请求。与跨站请求伪造&#xff08;CSRF&#xff09;相比&#xff0c;SSRF攻击针对的是服务器而不是用户。了解SSRF攻击的工作原理、如何防御它&#xff0…

手写OpenFeign(简易版)

Remoting组件实现 1. 前言2. 原理说明3. 远程调用组件实现---自定义注解3.1 添加Spring依赖3.2 编写EnableRemoting注解3.3 编写RemoteClient注解3.4 编写GetMapping注解 4. 远程调用组件实现---生成代理类4.1 编写自定义BeanDefinition注册器4.2 编写自定义包扫描器4.3 编写Fa…

JVM初识

什么是JVM&#xff1f; JVM全称是Java Virtual Machine&#xff0c;中文译名Java虚拟机。 JVM本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件。 JVM的功能 jvm的功能主要分为三部分&#xff1a; 解释和运行 对字节码文件中的指令&#xff0c;实…

vue实现导出+ 样式修改

1.安装插件 npm xlsx-style ^0.18.5 npm install xlsx -S ^0.8.13 2. 修改代码 node_modules里面找到 以下位置xlsx.js 搜索 write_ws_xml_data 替换成以下代码 function write_ws_xml_data(ws, opts, idx, wb) {var o [], r [], range safe_decode_range(ws[!ref]…