JVM-系统初始化

【硬刚JVM】JVM 专题三:类加载子系统(一)类装载器子系统 本文是对《【硬刚大数据之学习路线篇】从零到大数据专家的学习指南(全面升级版)》的JVM部分补充。 类装载器子系统 1.1 什么是类装载子系统? 类装载器子系统负责从文件系统或者网络中加载Class文件,Class文件在文件开头有特定的文件标识(魔数)。 类装载器子系统(ClassLoader)只负责Class文件的加载,至于它是否可以运行,则由Execution Engine决定。 |你妈妈[ClassLoader]给你[Execution Engine]找到相亲姑娘,是否能成得看你自己的本事. 阅读详情

系统初始化入口是JNI_CreateJavaVM函数,位于YourProjPath/hotspot/src/share/vm/prims/jni.cpp中,hotspot代码中的prims模块里面定义的就是一些外部接口,供JDK或者其他应用程序调用。
为了加深印象,我们先复习下JNI_CreateJavaVM函数是怎么来的。入口main函数中创建了运行JavaMain的主线程,在主线程中会调用InitializeJVM来对虚拟机进行初始化,InitializeJVM中通过InvocationFunctions结构体中的函数指针来调用CreateJavaVM,这个CreateJavaVM是通过dlsym(libjvm, "JNI_CreateJavaVM")获取到的。


系统初始化

JNI_CreateJavaVM函数中做的主要工作:
1.通过CAS判断vm_created变量是否为1,来保证当前只有一个JVM被创建
2.调用Threads::create_vm()来创建虚拟机
3.分别处理创建成功和失败的后续工作
所以想要知道真正的创建虚拟机的过程,我们需要去Threads::create_vm()中一探究竟。这个函数做了大量的工作,初始化了绝大多数Hotspot内核模块。由于代码极其的长,贴上之后影响阅读,可自行去hotspot/src/share/vm/runtime/thread.cpp下查看,从函数名称中可以大概看出都有哪些流程,接下来我们对其中一些重要步骤做详细分析。

  • 初始化一些版本信息
  • 初始化流输出模块
  • 处理launcher属性
    包括-Dsun.java.launcher和-Dsun.java.launcher.pid属性
  • 初始化os
    os::init()函数,位于hotspot/src/os/linux/vm/os_linux.cpp,用于初步初始化一些linux系统相关内容,主要包括:
    1.初始化随机数产生器种子
    2.设置内存页大小
    3.初始化系统信息
    4.获取原生主线程句柄
    5.初始化时钟
  • 初始化系统属性
    与操作系统相关的属性,详细代码位于hotspot/src/share/vm/runtime/arguments.cpp中的void Arguments::init_system_properties()函数
  • 初始化JDK版本
  • 初始化/升级JDK版本特定的系统属性
  • 解析程序参数
  • 初始化和应用ergonomics
    jvm ergonomics主要用于根据机器配置选择JVM内存参数和gc策略等等。
    init_before_ergo主要初始化了大内存页。
    Arguments::apply_ergo()根据机器的内存、CPU等等硬件信息,初始化了一些JVM内存参数、gc策略、根据CPU不同选择不同策略的BiasedLocking(偏向锁)等等内容,还初始化了JDK8取消持久带新增的Metaspace区。
  • 启动timer,用于统计一些JVM启动信息
  • 再次初始化os
    os::init_2()函数,位于hotspot/src/os/linux/vm/os_linux.cpp,和os::init()不同的是,os::init()用于初始化一些固定配置,os::init_2()根据外部传进来的参数来进行配置,os::init_2()初始化了以下内容:
    1.初始化快速线程时钟
    2.使用mmap分配一个只读单页内存供safepoint polling使用
    safepoint是JVM中很重要的一个概念,在很多场景下都会看到,特别是在GC时。safepoint是指一些特定的位置,当线程运行到这些位置时,线程的一些状态可以被确定。
    3.使用mmap分配memory_serialize_page
    memory_serialize_page是用来在不使用memory barrier系指令的场景下模拟其操作,这样VM Thread可以在Java线程状态发生变化时,及时获取到它们的状态,以正确地进行safe point时的管理。
    4.初始化内核信号,安装信号处理handler
    5.设置线程栈大小,设置线程初始栈
    6.初始化libpthread
    7.设置linux最大fd数量
    8.设置用于串行化线程创建的时钟
    9.若开启PerfAllowAtExitRegistration选项,向系统注册atexit函数
    10.初始化线程优先级策略
    以上可能有很多概念还不是很理解,这没关系,到后面随着一步步对hotspot了解的加深,很多问题都会豁然开朗,这里只是对hotspot启动时做了哪些工作有个大致了解即可。
  • 配置好os后再做一步参数调整
  • 初始化TLS
    ThreadLocalStorage::init();
  • 初始化输出流log
  • 加载系统库
    在解析JVM配置选项的时候,Arguments模块根据虚拟机选项-Xrun将要加载的本地库加入到_libraryList中,根据-agentlib -agentpath选项将要加载的本地代理库加入到_agentList中,当这些库被加载进虚拟机进程后,虚拟机将在库中查找函数符号JVM_Onload或者Agent_OnLoad并调用该函数,实现这些库与虚拟机的连接。
  • 初始化全局数据结构
    void vm_init_globals() {
    check_ThreadShadow();
    basic_types_init();
    eventlog_init();
    mutex_init();
    chunkpool_init();
    perfMemory_init();
    }
    1.初始化java基本类型系统
    2.初始化事件队列
    3.初始化全局锁
    4.初始化chunkpool
    这是hotspot实现的内存池,包括_large_pool,_medium_pool,_small_pool和_tiny_pool,这样系统就不必执行malloc/free
    5.初始化JVM性能统计数据区(PerfData),由选项UsePerfData设置。
  • 创建JavaThread
    在openjdk中,一个Java线程背后涉及到许多数据结构,Java层面是java.lang.Thread,hotspot层面是JavaThread -> OSThread,native层面是pthread_create()创建的线程。
    java中:
    class Thread implements Runnable {
      private long           eetop;
    }
    eetop就是指向JavaThread的指针。
    hotspot中,Thread用于记录平台无关信息,OSThread记录平台相关信息。
    class Thread: public ThreadShadow {
    OSThread* _osthread;
    }
    class JavaThread: public Thread {
    }
    有了以上知识,我们来看JavaThread的创建:
    JavaThread* main_thread = new JavaThread();
    main_thread->set_thread_state(_thread_in_vm);
    main_thread->record_stack_base_and_size();
    main_thread->initialize_thread_local_storage();
    main_thread->set_active_handles(JNIHandleBlock::allocate_block());
    if (!main_thread->set_as_starting_thread()) {
    vm_shutdown_during_initialization(
      "Failed necessary internal allocation. Out of swap space");
    delete main_thread;
    *canTryAgain = false; // don't let caller call JNI_CreateJavaVM again
    return JNI_ENOMEM;
    }
    main_thread->create_stack_guard_pages();
    首先创建了一个JavaThread类型的main_thread,set_thread_state将线程状态设置为_thread_in_vm,表示该线程处于在JVM中执行的状态,record_stack_base_and_size记录线程栈的基址和大小,initialize_thread_local_storage初始化线程本地存储区TLS,set_active_handles为线程设置JNI句柄,set_as_starting_thread为JavaThread创建了OSThread,并Store pthread info into the OSThread,create_stack_guard_pages初始化这个线程栈。
  • 初始化Java的对象监视器
    java的关键字synchronized就是通过对象监视器实现的
  • init_globals()函数
    这个函数实现了对全局模块的初始化,代码位于hotspot/src/share/vm/runtime/init.cpp。这些模块是Hotspot的整体基础,后面会对这些模块分别分析
  • 将创建的main_thread加入线程队列
  • 创建VMThread
    VMThread用于执行VMOptions,VMOptions实现了JVM内部的核心操作,为其他运行时模块以及外部程序接口服务。VMThread创建成功后不断等待、接受并执行指定的VMOptions。
  • 初始化主要的JDK类
  • 创建Java层Thread
    在java.lang.Thread类初始化好之后,创建了java.lang.Thread,设置到刚才创建的JavaThread中去,main_thread->set_threadObj(thread_object);,同时这个main_thread也被设置给了java.lang.Thread的eetop。
    到这里,java版的main线程就被创建好了,所以现在就是java.lang.Thread中有JavaThread,JavaThread中有OSThread,OSThread中又有pthread也就是native thread,这里的pthread才是真正的可以被操作系统执行的线程,其他的都只是一些结构体,而且这里的pthread就是上一节中分析启动流程时说过的通过pthread_create的主线程,真正的java main函数在这个线程中执行。
  • 创建一些守护进程
    JVM初始化完毕,比较难的是弄清这些线程之间的关系。

nRF开发环境搭建全攻略:VS Code + nRF Connect SDK + Zephyr实战 嵌入式开发中,环境配置往往是新手入门的第一道障碍,尤其面对基于Zephyr RTOS的Nordic nRF平台时,工具链的复杂度常让人望而却步。理解构建系统、SDK版本管理和调试工具之间的协作关系,是高效开发的前提。Zephyr作为开源实时操作系统,通过设备树和Kconfig实现硬件描述与功能配置,而nRF Connect SDK(NCS)则是Nordic基于Zephyr的增强发行版,两者结合为物联网开发提供了强大支持。基于VS Code搭建开发环境,配合west工具管理多仓库、CMake/Ninja执行构 阅读详情

相关推荐

全球第一开源云ERP Odoo操作手册 模块安装和界面汉化指南

Odoo 的功能包含在不同的模块中, 刚创建的数据库除 Odoo 的核心模块外, 其它模块并没有被安装到系统中,你可以根据需要安装它们。本节将介绍安装模块和界面汉化的相关知识。

weixin_44793763的博客 2073

安卓高版本c/c++调用java,通过JNI_CreateJavaVM/JNI_GetCreatedJavaVMs创建虚拟机实例

c/c++调用java;JNI_CreateJavaVM/JNI_GetCreatedJavaVMs创建虚拟机实例;libnativehelper; JNI_CreateJavaVM运行挂载libart

我的博客 2422

联想Y9000P安装Ubuntu20.04记录

联想Y9000P 2022安装Ubuntu20.04问题记录

Legendyyy的博客 7115

jni_CreateJavaVm详解

jni_CreateJavaVm详解   1.确保只有一个线程调用这个方法并且确保只创建一个hotspot vm 实例。因为hotspot vm   创建的静态数据结构无法再次初始化,所以一旦初始化到某个确定点后,进程空里只能有一   个hotspot vm。   2.检查并确保支持当前的jni版本,初始化垃圾收集日志的输出流。   3.初始化os模块,如当前进程id、内存页尺寸,   4.解析传...

一人一屋淋雨声 9058

Avalonia 项目结构说明

Avalonia UI

bjxingch的博客 1271

Avalonia 超级详细学习指南

什么是 Avalonia?Avalonia 是一个开源的、跨平台的 GUI 框架,允许开发者使用 XAML 和 C# 构建现代化、高性能的桌面应用程序。与其他框架相比,Avalonia 具有强大的跨平台能力和灵活的界面设计。} }()Avalonia 的特点和优势跨平台性:Avalonia 可以在 Windows、Linux、macOS 等多个平台上运行,开发者可以编写一套代码,然后在不同的操作系统上运行相同的应用程序。

仰望星空的博客 1万+

JNI基础(一)

(一) 什么是JNI? JNI官网介绍 Java调用C/C++在Java语言里面本来就有的,并非Android自创的,即JNI。JNI就是Java调用C++的规范。当然,一般的Java程序使用的JNI标准可能和android不一样,Android的JNI更简单。 JNI,全称为Java Native Interface,即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C++机型交互。即可以在Java代码中调用C/C++等语言的代码或者在..

做的过程自我总结 713

XYC Q8开源掌机刷第三方系统教程

分区结束后直接将各种游戏文件放入OD分区的Roms文件夹下

m0_60352504的博客 4567

C 语言调用 JNI_CreateJavaVM

C 语言调用 JNI_CreateJavaVM 环境:win10 + vs2015 + jdk-8u171-windows-x64.zip 假设我们已经存在了 C/C++ 语言的动态库clib.dll,如果想从 java 语言调用此动态库clib.dll,需要写个供 java 调用的C/C++的JNI动态库: clib_jniwrapper.dll,clib_jniwrapper.dll 桥接了从Java(JNIWrapper)对象到C/C++对象(clib.dll)的转换。 然后再写个 java 类如:

恒 2665

关于如何在matlab中导入并翻译Hypemesh导出的大型刚度矩阵txt文本

如何将它翻译成matlab可以使用的矩阵变量,并参与运算。 由于这个大型刚度矩阵125万x125万≈1e12。matlab甚至其他计算软件无法保存这个大的一个矩阵文件。而这个刚度矩阵作为稀疏矩阵其中非零元素的数目只有有500多万。采用sparse稀疏矩阵技术是可以保存。 这里简单介绍一下这个Hypemesh导出的大型刚度矩阵txt文本。如图DMIG开头的标识符是换行符,后面两列是表示这条非零元素在刚度矩阵中列数的信息。我们已经将左边字母和符号等批量删除,得到了右边textread函数可以...

wenyusuran的专栏 1795

31、贝叶斯认知建模与隐马尔可夫模型:理论与应用

本文探讨了贝叶斯认知建模与隐马尔可夫模型(HMM)的理论基础及其在认知科学和神经科学中的应用。重点介绍了贝叶斯定理和HMM的基本原理,并结合实际案例,如情绪识别系统和脑机接口(BCI),展示了它们在处理复杂认知任务中的强大能力。文章还讨论了贝叶斯-HMM模型的技术细节、优势与局限性,以及未来的发展前景。

meat5的博客 141

window JNI_CreateJavaVM启动java程序

https://blog.youkuaiyun.com/earbao/article/details/51889605 #define _CRT_SECURE_NO_WARNINGS 1       #include <stdio.h>   #include "jni.h"   #include <stdlib.h>   #include &l...

weixin_34061555的博客 1076

windows中搭建sonic云真机环境/云真机环境搭建-基于docker容器部署

基于Windows系统搭建Sonic远程云真机环境实现通过浏览器操作手机端系统

雾林小妖的博客 1015

JVM类加载子系统的流程(加载阶段、链接阶段和初始化阶段)

一、类加载子系统的作用 1.类加载子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识。 2.ClassLoader只负责class文件的加载,至于它是否可以运行,则由ExecutionEngine(执行引擎)决定。 3.加载的类信息存放在一块成为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射) 举例:类加载.........

a2321123的博客 690

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

jvm类加载子系统之类的初始化

文章目录前言一、具体描述二、的线程安全问题主动使用 前言 语雀地址:https://www.yuque.com/yangxiaofei-vquku/wmp1zm/dmz2gd 一、具体描述 类的初始化是类装载的最后一个阶段。如果前面的步骤都没有问题说明类可以被顺利装载到系统中,此时jvm才会执行类中的字节码(即到了初始化阶段才真正开始执行类中定义的java程序代码)。 初始化阶段就是执行类初始化方法()的过程 此方法不需要程序员定义,是javac编译器自动收集类中所有类变量的赋值动作和静态代码..

yangxiaofei_java的博客 451

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

JVM类加载子系统 (ClassLoader) - 加载,链接,初始化

类加载子系统 完整图 类加载器子系统作用 类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识。(例如:CA FE BA BY) ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine(执行引擎)决定。 加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射) class fi

后端学习 441

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

《剑指JVM》——第19章6——初始化2类的初始化时机——类装载子系统6

🔥本篇概览:详细讲解了《剑指JVM》——第19章6——链接4类的初始化时机——类装载子系统6🌈⭕🔥

做一个善良的人,做好自己的事,如果愿意,再发一份光。 660

《剑指JVM》——第19章5——初始化1——类装载子系统5

🔥本篇概览:详细讲解了《剑指JVM》——第19章5——链接4解析——类装载子系统5🌈⭕🔥

做一个善良的人,做好自己的事,如果愿意,再发一份光。 1178

java初始化系统代码简析_JVM源码分析之堆内存的初始化

简书占小狼转载请注明原创出处,谢谢!看得越多,懂的越少,还年轻,多学习!前言《Java GC的那些事》一文中说过:Java堆是被所有线程共享的一块内存区域,所有对象和数组都在堆上进行内存分配。为了进行高效的垃圾回收,虚拟机把堆内存划分成新生代、老年代和永久代(1.8中无永久代,使用metaspace实现)三块区域。堆初始化Java堆的初始化入口位于Universe::initialize_heap...

weixin_35426348的博客 158

c++自定义类对象的初始化_JVM类加载子系统解毒

‍ 导读:“带着问题,尤其是面试问题的学习才是最高效的。加油,奥利给!”直击面试看你简历写得熟悉JVM,那你说说类的加载过程吧?我们可以自定义一个String类来使用吗?什么是类加载器,类加载器有哪些?多线程的情况下,类的加载为什么不会出现重复加载的情况?什么是双亲委派机制?它有啥优势?可以打破这种机制吗?类加载子系统类加载机制概念Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进...

weixin_42349126的博客 111

c++自定义类对象的初始化_JVM解毒——类加载子系统

> 点赞+收藏 就学会系列,文章收录在 GitHub [JavaEgg](Jstarfish/JavaEgg) ,N线互联网开发必备技能兵器谱直击面试看你简历写得熟悉JVM,那你说说类的加载过程吧?我们可以自定义一个String类来使用吗?什么是类加载器,类加载器有哪些?多线程的情况下,类的加载为什么不会出现重复加载的情况?什么是双亲委派机制?它有啥优势?可以打破这种机制吗?类加载子系统类加...

weixin_42298100的博客 143

一文理解JVM的类加载系统

}该类是如何一步步被加载的呢?加载的过程如下所示:第一步:加载阶段,字节码文件会以文件流的形式输入,JVM会读取并加载这些字节码文件。第二步:链接阶段,对字节码进行验证、初步的处理,并将常量池内的符号引用转换为直接引用等等。第三步:初始化阶段,这一阶段主要是创建对象了。每个阶段又有更具体的功能,如下图所示:接下来,我们先介绍每个组件的功能,然后再从源码等角度来看整个系统是如何工作的。

纵横千里 捭阖四方 的专栏 453

JVM 类加载子系统在干什么?

JVM 类加载子系统在干什么?

liuruiaaa的博客 990

JVM-类加载子系统

本文和大家聊聊 JVM 的基本概念和类加载子系统。

DC1020的博客 1296

如何用AI自动解决JVM内存初始化错误

于是我尝试用AI辅助开发的方式,快速构建了一个自动诊断和修复工具,效果非常不错,分享下我的实现思路。最方便的是部署功能,完成开发后一键就能发布成可访问的Web服务,自动处理了服务器配置等繁琐问题。总结下经验:对于JVM内存问题,AI辅助开发的优势在于能快速整合系统信息、行业最佳实践和具体场景需求。使用AI模型评估当前配置的合理性,考虑因素包括:系统总内存、其他进程内存占用、JVM开销(如元空间、线程栈等)。加入AI算法分析历史内存使用模式,预测应用的实际内存需求,避免简单按比例分配导致的浪费或不足。

AmberLeopard26的博客 590

什么是jvm

JVM是Java程序的运行环境,它同时也是一个操作系统的一个应用程序、一个进程,因此他也有他自己的运行生命周期,也有自己的代码和数据空间.JVM包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。首先来说一下JVM工作原理中的jdk这个东西,不管你是初学者还是高手,是j2ee程序员还是j2se程序员,jdk总是在帮我们做一些事情.我们在了解Java之前首先大师们会给...

a5504250的博客 230
上一篇: Java虚拟机的启动与程序的执行
下一篇: Java虚拟机 对象的创建与OOP-Klass模型
DViewer
博客等级 码龄16年 16粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值