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

JVM内存模型以及类加载过程分析

写在前面JVM内存模型可以说是面试中常客了足见其重要性本文就一起来看下以求下次遇到这样的面试题可以把面试官按在地上摩擦摩擦我的滑板鞋霍霍1JVM内存模型先来看一下JVM内存模型的图其中线程共享的区域有方法区堆。线程独享的区域有程序计数器虚拟机栈本地方法栈。我们按照线程独享还是共享来分别看下。1.1线程独享1.1.1:程序计数器用来存放线程执行字节码位置的区域因为只是存储一个位置所以是一块很小的内存空间。也是唯一的一块不会发生内存溢出的区域。1.1.2:虚拟机栈线程执行方法时分配线程栈的区域每个线程一个线程栈每次方法的调用都会生成对应的栈帧并压入线程栈中如下图每个栈帧中包含了执行方法所必须的内容主要是局部变量表操作数栈异常表等如下图通过参数-Xss来设置虚拟机栈的大小。1.1.3:本地方法栈同虚拟机栈不过是用来执行native方法的底层通过C语言编写。1.2线程共享1.2.1堆堆是JVM中最大的一块内存区域通过-Xmssize,-Xmxsize来设置堆内存的最小值和最大值一般最好二者设置为一致这样可以避免扩容时申请内存对程序的影响。堆分为年轻代和年老代其中年轻代又分为Eden和survivorsurvivor又分为from和to相关主要参数如下-Xmssize:设置堆内存最小值 -Xmxsize:设置堆内存最大值 -Xmnsize:设置年轻代大小 -XX:NewRatioratio设置年老代和年轻代比例优先级低于-Xmn。 例如-XX:NewRatio3表示老年代:年轻代 3:1年轻代占堆的1/4。如果设置了-Xmn则此参数失效。适合通过比例调整不关心精确大小。 -XX:SurvivorRatioratioeden和单个survivor的比例 例如-XX:SurvivorRatio4表示Eden:From 4:1Eden占年轻代的4/6。Survivor过小可能导致对象过早晋升过大则浪费空间。以1.8为例看下结构图注意图中的元空间不属于堆属于本地内存1.2.2方法区这里方法区是一个抽象的概念是JVM规范中的一部分内容永久代和元空间都是其具体的实现永久代是1.8之前对于方法区的实现而元空间是1.8版本对于方法区的实现用来替换永久代。方法区主要用来存储类的元信息如类成员变量类方法信息运行时常量池等。2类加载到执行过程分析2.1类加载为了更加清晰的展示类加载整个过程我们通过一个实际的类在不同的加载过程中对于jvm内存模型的影响来看下如下类packagecom.demo.xx;publicclassJVMCase{// 常量publicfinalstaticStringMAN_SEX_TYPEman;// 静态变量publicstaticStringWOMAN_SEX_TYPEwoman;publicstaticvoidmain(String[]args){StudentstunewStudent();stu.setName(nick);stu.setSexType(MAN_SEX_TYPE);stu.setAge(20);JVMCasejvmcasenewJVMCase();// 调用静态方法print(stu);// 调用非静态方法jvmcase.sayHello(stu);}// 常规静态方法publicstaticvoidprint(Studentstu){System.out.println(name: stu.getName(); sex:stu.getSexType(); age:stu.getAge());}// 非静态方法publicvoidsayHello(Studentstu){System.out.println(stu.getName()say: hello);}}classStudent{Stringname;StringsexType;intage;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicStringgetSexType(){returnsexType;}publicvoidsetSexType(StringsexType){this.sexTypesexType;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.ageage;}}假定执行了程序new JVMCase(),正式开始加载过程首先执行第一个阶段加载会通过类加载器app classload将字节码加载到方法区中这没什么好说的。接着看连接阶段连接阶段又分为验证准备解析首先是验证阶段验证文件的合法性即格式是否符合JVM的要求等。然后是准备阶段准备阶段会为静态变量申请内存并赋予初始值对于常量public final static String MAN_SEX_TYPE man;会直接赋值man对于静态变量public static String WOMAN_SEX_TYPE woman;会赋予String的默认值null如下图接着是解析解析阶段是将符号引用如字面量com.xx.Stu#sayHi解析为实际引用com.xx.Stu#sayHi对应的可以直接使用的指针地址。到这里连接阶段就结束了进入初始化阶段,该阶段会执行clinit方法该方法是在编译阶段编译器收集类中的静态变量静态代码块动态生成的方法本例中clinit方法如下仅示意:function clinit() { WOMAN_SEX_TYPE woman; }初始化结束后WOMAN_SEX_TYPE就会被赋值为woman了如下图2.2main方法执行执行main首先会为main线程在虚拟机栈中分配一个线程栈然后创建main方法的栈帧压入线程栈开始执行main方法执行代码Student stu new Student();后就会在堆中创建stu对象在栈帧的局部变量表中引用堆中的对象如下同样的执行JVMCase jvmcase new JVMCase();会在堆中创建对应的对象接着执行实例方法jvmcase.sayHello(stu);和静态方法print(stu);,此时如下图图示可能不是百分百的正确知道大概的意思就行有时候不用抠的那么细。我觉得知道核心的流程就可以了如果真的需要再详细的了解细节也不迟写在后面参考文章列表多知道一点clinit方法这是在编译阶段编译器通过收集静态变量静态代码块而构成的一个方法代码的顺序是程序的自然顺序会在初始化阶段来执行另外如果有父类的话会先执行父类的clinit方法如下类packagecom.demo.xx;publicclassFather{static{fatherStatic0;System.out.println(father 静态代码块);}privatestaticintfatherStatic1;publicstaticvoidmain(String[]args){}}packagecom.demo.xx;publicclassSonextendsFather{privatestaticintsonStatic1;static{sonStatic0;System.out.println(son 静态代码块);}publicstaticvoidmain(String[]args){System.out.println(sonStatic最终值是sonStatic);}}运行father 静态代码块 son 静态代码块 sonStatic最终值是0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------

相关文章:

JVM内存模型以及类加载过程分析

写在前面 JVM内存模型可以说是面试中常客了,足见其重要性,本文就一起来看下,以求下次遇到这样的面试题可以把面试官按在地上摩擦,摩擦,我的滑板鞋,霍霍!!! 1:…...

IT行业新风向!卷运维不如卷网络安全

在网络安全行业摸爬滚打这么多年,亲历了数不尽的技术面试,同时也见证了同行们职业生涯的起起伏伏,特别是运维领域。我发现最近很多从事运维的选择了辞职,转行到了网络安全这个发展路线。 运维,顾名思义就是运营和维护…...

PHP扩展管理新革命:PIE替代PECL

告别PECL,拥抱PIE:像Composer一样管理PHP扩展 PHP扩展的传统管理方式依赖PECL(PHP Extension Community Library),但PECL存在依赖管理混乱、版本控制困难等问题。PIE(PHP Extension Installer)作…...

最长连续序列:O(n)最优解法详解

最长连续序列问题概述 给定一个未排序的整数数组,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。要求算法的时间复杂度为 O(n)。 示例: 输入:nums [100,4,200,1,3,2] 输出:4 解释&#xf…...

TensorFlow与PyTorch:神经网络构建双雄

构建神经网络的两大核心工具:TensorFlow与PyTorch 神经网络已成为现代人工智能的核心技术之一,广泛应用于图像识别、自然语言处理、推荐系统等领域。构建神经网络的两大核心工具是TensorFlow和PyTorch,它们提供了高效的框架和丰富的功能&…...

掌握Git命令,高效管理代码

常用的 Git 命令 Git 是当前最流行的分布式版本控制系统,广泛应用于软件开发中。掌握常用的 Git 命令对于高效管理代码库至关重要。以下是一些常用的 Git 命令及其使用场景。 初始化与克隆仓库 要开始使用 Git,首先需要初始化一个新的仓库或克隆一个现有…...

从手动搬砖到自动化运营:我的Twitter多账号管理痛苦自救指南

昨天和一个做跨境的朋友聊天,他给我看了他的电脑桌面——16个Chrome标签页,全是不同Twitter账号的登录界面。他说每天光切换账号发内容就要花3个多小时,手指头都快点抽筋了。我太懂这种感觉了。入行做海外推广三年,从最开始管3个号…...

uniflash烧录报错--Error on line 1191 : Undefined Record Type

我烧录的是boot和app层程序,没有合并,直接烧录,报错:Error on line 1191 : Undefined Record Type。当检查过烧录文件路径正常且烧录文件没错之后,我一直不明白问题出在哪里。最后发现,公司的烧录文件经过烧…...

CUDA 13.0:ARM生态革命与GPU共享突破

CUDA 13.0深度解析:统一ARM生态、UVM增强与GPU共享的革命 统一ARM生态支持 CUDA 13.0标志着NVIDIA在异构计算领域的重大突破,首次实现对ARM架构的全面支持。这一特性使得开发者能够在基于ARM的服务器(如NVIDIA Grace CPU)或移动设…...

位深度如何提升机器视觉精度

位深度的定义 位深度(Bit Depth)指数字图像中每个像素用于表示颜色的二进制位数。常见的位深度包括8位、10位、12位、16位等。例如,8位深度图像每个像素有256(2^8)种可能的灰度或颜色值。位深度越高,图像能…...

MIT 6.824-lab3A(实现思路)

目录 前言 一、引子 二、3A实现 2.1 结构体设计 每个节点应有的状态: 定义一些枚举常量: raft结构体 2.2 RPC 结构(RequestVote / AppendEntries) 2.3 raft节点初始化 2.4 定时检测的go协程ticker 2.5 开始选举 startE…...

瑞萨RH850串口烧录说明

1.1 环境配置软件:Renesas flash programmer 下载链接:Renesas Flash Programmer (Programming GUI) | Renesas 硬件:通用串口工具即可1.2 硬件配置1. 查看是否为瑞萨通用标准。若不是标准口,只需确认TDO , TDI , FPMD0 &#xff…...

从入门到进阶:AI系统学习全路径指南,助你少走弯路,快速成为AI高手!

从入门到进阶:AI系统学习全路径指南 引言/痛点 很多想踏入AI领域的同学都会陷入“不知道从哪开始、学了零散知识没体系、越学越迷茫”的困境——AI涵盖机器学习、深度学习、大模型、CV、NLP等多个分支,没有清晰的路径很容易走弯路。本文将给出一套可落地…...

Comsol 弹性波晶体板能带计算及模态区分探索

comsol弹性波晶体板能带计算,包含模态区分。在研究弹性波在晶体板中的传播特性时,能带计算是一项至关重要的任务,而 Comsol 作为一款强大的多物理场仿真软件,为我们提供了便捷且高效的工具来实现这一目标。今天,咱们就…...

2026论文降重神器盘点:AIGC痕迹权威评测含免费试用

【CSDN导读】 2026年的毕业季,高校对“AIGC痕迹”的审查严苛程度史无前例。传统的同义词替换降重工具不仅双双失效,甚至面临“越改AI味越重”的尴尬境地。本文首发独家深度评测,从底层的算法逻辑出发,为你横向对比市面5款主流工具…...

KingbaseES聚焦上线:性能飙升的奥秘

KingbaseES聚焦产品上线:技术解析与实践指南 KingbaseES作为一款国产高性能关系型数据库,近期推出的“聚焦产品上线”功能备受关注。该功能通过优化查询执行计划、资源分配和并发控制,显著提升了高负载场景下的数据库性能。以下从技术实现、应…...

排列问题回溯解法全解析

P4163 [SCOI2007] 排列问题解析 排列问题是算法竞赛中的经典问题,涉及对给定数字或字符的全排列生成与处理。P4163题目要求生成所有不重复的排列,并可能对排列进行特定操作或统计。以下将详细分析该问题的解法,并提供代码实现。 问题描述 给定…...

C语言贪吃蛇实战教程

贪吃蛇游戏概述 贪吃蛇是一款经典的游戏,玩家控制一条蛇在屏幕上移动,通过吃食物来增长身体长度,同时避免撞到墙壁或自身。该游戏适合作为C语言的实战项目,能够帮助开发者掌握基础语法、数组操作、键盘输入处理等核心概念。 开发环…...

Android主线程Looper机制解析

主线程Looper消息循环的建立机制 在Android系统中,主线程的消息循环是通过Looper、MessageQueue和Handler协同工作实现的。主线程在启动时自动初始化Looper,形成一个持续运行的消息处理机制。这种设计使得Android能够高效处理UI事件、系统消息和用户交互…...

解决Linux克隆后IP冲突的30字指南

克隆后IP地址和源Linux主机相同的问题分析 在虚拟化或克隆Linux主机时,经常遇到克隆后的系统与源主机IP地址相同的情况。这会导致网络冲突,使两台主机无法同时在线。该问题通常源于系统克隆过程中未正确处理网络配置文件的唯一性。 Linux系统的网络配置信…...

快速掌握网络协议的7个高效方法

理解协议的基本概念和结构 学习任何网络协议的第一步是理解其基本概念和结构。网络协议定义了设备之间通信的规则和格式。常见的协议如HTTP、TCP/IP、MQTT等,都有其特定的用途和工作方式。通过阅读协议的官方文档或RFC(Request for Comments)…...

探索光伏 + 混合储能三相并网的超级电容能量管理

光伏混合储能三相并网超级电容能量管理 1、光伏MPPT最大功率跟踪 2、混合储能采用低通滤波器进行功率分配,可有效抑制功率波动, 3、对超级电容的soc进行能量管理,soc较高时多放电,较低时少放电, soc较低时状态与其相反…...

Go数据结构与排序算法实战

Go语言中的数据结构与排序算法 Go语言以其简洁和高效著称,适合处理各类数据结构和算法问题。本文将介绍Go中常用的数据结构如数组、切片、链表、栈、队列、哈希表,以及排序算法如快速排序、归并排序、堆排序等,并提供代码示例。 数据结构 数组…...

移动端1px边框终极解决方案

HTML 中的 1px 问题解析 在移动端开发中,1px 问题是一个常见的挑战。由于高分辨率屏幕(如 Retina 显示屏)的普及,1px 的 CSS 像素可能被渲染为多个物理像素,导致边框或线条看起来比实际更粗。这种现象在移动设备上尤为…...

多维时序:基于DNN深度神经网络的多变量时间序列预测探索

多维时序 | 基于DNN深度神经网络多变量时间序列预测(考虑历史特征的影响) 【关键词】:Matlab;DNN回归;滑动窗口;多变量历史特征 【实物】: 1)案例包括一个多输入单输出回归问题 2)案例采用滑动…...

经验谈:如何为你的IoT设备选择一个“靠谱”的网口?(RJ45+变压器篇)

问题场景描述 “调试一款新的网关设备,发现长时间运行后网络偶发断连,ping测试丢包率异常……” 这样的问题,除了排查驱动和软件配置,硬件层面的原因常常聚焦在 网络接口部分。本文将分享几个常见的硬件“坑点”及解决方案。 常见…...

邀请函|鲁欧智造邀您共赴SEMICON China 2026

诚挚邀请鲁欧智造诚挚邀请您出席SEMICON China 2026 上海国际半导体展览会,展会将于2026年3月25日—3月27日在上海新国际博览中心隆重举行。作为亚太地区规模最大、影响力最广的半导体全产业链盛会,本届展会汇聚全球超 1400 家行业领军企业,覆…...

基于PSO-LSTM的时间序列预测:新手友好MATLAB实战

PSO-LSTM时间序列,基于粒子群算法优化长短期记忆神经网络(PSO-LSTM)的时间序列预测需要分类和回归也可更换 MATLAB代码,中文注释清晰,非常适合新手小白 替换数据即可运行, 推荐2018B以上版本, 在时间序列预测领域&…...

矩阵键盘工作原理与实战技巧

矩阵键盘的工作原理 矩阵键盘通过行列扫描方式减少I/O口占用。常见4x4矩阵键盘使用8个引脚(4行4列)实现16个按键检测,相比独立按键节省引脚资源。其核心原理是逐行输出低电平并检测列线状态,当某键按下时对应行列线导通&#xff0…...

51单片机-实现红外遥控模块教程

51单片机实现红外遥控模块教程 红外遥控技术广泛应用于家电、智能设备等领域,51单片机因其成本低、易上手的特点,常被用于解码和发送红外信号。以下教程详细讲解如何利用51单片机实现红外遥控模块的接收与发送功能,包含硬件连接、信号解码原理…...