二、JVM-深入运行时数据区

news2024/11/13 14:55:20

深入运行时数据区

计算机体系结构

JVM的设计实际上遵循了遵循冯诺依曼计算机结构

image.png

CPU与内存交互图:

image.png

硬件一致性协议:

MSI、MESI、MOSI、Synapse、Firely、DragonProtocol

摩尔定律

摩尔定律是由英特尔(Intel)创始人之一戈登·摩尔(Gordon Moore)提出来的。其内容为:当价格不变时,集成电路上可容纳的晶体管数目,约每隔18个月便会增加一倍,性能也将提升一倍。换言之,每一美元所能买到的电脑性能,将每隔18个月翻两倍以上。这一定律揭示了信息技术进步的速度。

为了使摩尔定律更为准确,在摩尔定律发现后10年,1975年的时候,摩尔又做了一些修改。将翻番的时间从一年半调整为两年。

常量池分类:

1.静态常量池

静态常量池是相对于运行时常量池来说的,属于描述class文件结构的一部分

字面量符号引用组成,在类被加载后会将静态常量池加载到内存中也就是运行时常量池

字面量 :文本,字符串以及Final修饰的内容

符号引用 :类,接口,方法,字段等相关的描述信息。

2.运行时常量池

当静态常量池被加载到内存后就会变成运行时常量池。

也就是真正的把文件的内容落地到JVM内存了

3.字符串常量池

**设计理念:**字符串作为最常用的数据类型,为减小内存的开销,专门为其开辟了一块内存区域(字符串常量池)用以存放。

JDK1.6及之前版本,字符串常量池是位于永久代(相当于现在的方法区)。

JDK1.7之后,字符串常量池位于Heap堆中

面试常问点:(笔试居多)

下列三种操作最多产生哪些对象

1.直接赋值

String a ="aaaa";

解析:

最多创建一个字符串对象。

首先“aaaa”会被认为字面量,先在字符串常量池中查找(.equals()),如果没有找到,在堆中创建“aaaa”字符串对象,并且将“aaaa”的引用维护到字符串常量池中(实际是一个hashTable结构,存放key-value结构数据),再返回该引用;如果在字符串常量池中已经存在“aaaa”的引用,直接返回该引用。

2.new String()

String a =new String("aaaa");

解析:

最多会创建两个对象。

首先“aaaa”会被认为字面量,先在字符串常量池中查找(.equals()),如果没有找到,在堆中创建“aaaa”字符串对象,然后再在堆中创建一个“aaaa”对象,返回后面“aaaa”的引用;
3.intern()

String s1 = new String("yzt");
String s2 = s1.intern();
System.out.println(s1 == s2); //false

解析:

String中的intern方法是一个 native 的方法,当调用 intern方法时,如果常量池已经包含一个等于此String对象的字符串(用equals(object)方法确定),则返回池中的字符串。否则,将intern返回的引用指向当前字符串 s1(jdk1.6版本需要将s1 复制到字符串常量池里)

常量池在内存中的布局:

image.png

运行时数据区(Run-Time Data Areas)

在装载阶段的第(2),(3)步可以发现有运行时数据,堆,方法区等名词
(2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
(3)在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口
说白了就是类文件被类装载器装载进来之后,类中的内容(比如变量,常量,方法,对象等这些数据得要有个去处,也就是要存储起来,存储的位置肯定是在JVM中有对应的空间)

2.3.1 官网概括

官网:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

The Java Virtual Machine defines various run-time data areas that are used during execution of a program. Some of these data areas are created on Java Virtual Machine start-up and are destroyed only when the Java Virtual Machine exits. Other data areas are per thread. Per-thread data areas are created when a thread is created and destroyed when the thread exits.

2.3.2 图解

Each run-time constant pool is allocated from the Java Virtual Machine's method area (§2.5.4).s

image.png

2.3.3 初步认识

2.3.3.1 Method Area(方法区)

(1)方法区是各个线程共享的内存区域,在虚拟机启动时创建

The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads. 
The method area is created on virtual machine start-up. 

(2)虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却又一个别名叫做Non-Heap(非堆),目的是与Java堆区分开来

Although the method area is logically part of the heap,......

(3)用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization.

(4)当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常

If memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an OutOfMemoryError.

此时回看装载阶段的第2步,将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构

如果这时候把从Class文件到装载的第(1)和(2)步合并起来理解的话,可以画个图
image.png

值得说明的

JVM运行时数据区是一种规范,真正的实现
在JDK 8中就是Metaspace,在JDK6或7中就是Perm Space

2.3.3.2 Heap(堆)

(1)Java堆是Java虚拟机所管理内存中最大的一块,在虚拟机启动时创建,被所有线程共享。

(2)Java对象实例以及数组都在堆上分配。

The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.
The heap is created on virtual machine start-up.

此时回看装载阶段的第3步,在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口

此时装载(1)(2)(3)的图可以改动一下

image.png

2.3.3.3 Java Virtual Machine Stacks(虚拟机栈)

经过上面的分析,类加载机制的装载过程已经完成,后续的链接,初始化也会相应的生效。

**假如目前的阶段是初始化完成了,后续做啥呢?肯定是Use使用咯,不用的话这样折腾来折腾去有什么意义?那怎样才能被使用到?换句话说里面内容怎样才能被执行?比如通过主函数main调用其他方法,这种方式实际上是main线程执行之后调用的方法,即要想使用里面的各种内容,得要以线程为单位,执行相应的方法才行。**那一个线程执行的状态如何维护?一个线程可以执行多少个方法?这样的关系怎么维护呢?

(1)虚拟机栈是一个线程执行的区域,保存着一个线程中方法的调用状态。换句话说,一个Java线程的运行状态,由一个虚拟机栈来保存,所以虚拟机栈肯定是线程私有的,独有的,随着线程的创建而创建。

Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread.

(2)每一个被线程执行的方法,为该栈中的栈帧,即每个方法对应一个栈帧。

调用一个方法,就会向栈中压入一个栈帧;一个方法调用完成,就会把该栈帧从栈中弹出。

 A Java Virtual Machine stack stores frames (§2.6). 
A new frame is created each time a method is invoked. A frame is destroyed when its method invocation completes.
  • 图解栈和栈帧
void a(){
b();
}
void b(){
c();
}
void c(){

}

image.png

  • 栈帧

官网:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6

栈帧:每个栈帧对应一个被调用的方法,可以理解为一个方法的运行空间。

每个栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向运行时常量池的引用(A reference to the run-time constant pool)、方法返回地址(Return Address)和附加信息。

局部变量表:方法中定义的局部变量以及方法的参数存放在这张表中
局部变量表中的变量不可直接使用,如需要使用的话,必须通过相关指令将其加载至操作数栈中作为操作数使用。
操作数栈:以压栈和出栈的方式存储操作数的
动态链接:每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接(Dynamic Linking)。
方法返回地址:当一个方法开始执行后,只有两种方式可以退出,一种是遇到方法返回的字节码指令;一种是遇见异常,并且这个异常没有在方法体内得到处理。

image.png

  • 结合字节码指令理解栈帧

javap -c Person.class > Person.txt

Compiled from "Person.java"
class Person {
...     
 public static int calc(int, int);
  Code:
   0: iconst_3   //将int类型常量3压入[操作数栈]
   1: istore_0   //将int类型值存入[局部变量0]
   2: iload_0    //从[局部变量0]中装载int类型值入栈
   3: iload_1    //从[局部变量1]中装载int类型值入栈
   4: iadd     //将栈顶元素弹出栈,执行int类型的加法,结果入栈
   5: istore_2   //将栈顶int类型值保存到[局部变量2]中
   6: iload_2    //从[局部变量2]中装载int类型值入栈
   7: ireturn    //从方法中返回int类型的数据
...
}

思考:index的值是0还是1

On class method invocation, any parameters are passed in consecutive local variables starting from local variable 0. On instance method invocation, local variable 0 is always used to pass a reference to the object on which the instance method is being invoked (this in the Java programming language). Any parameters are subsequently passed in consecutive local variables starting from local variable 1.

2.3.3.4 The pc Register(程序计数器)

我们都知道一个JVM进程中有多个线程在执行,而线程中的内容是否能够拥有执行权,是根据CPU调度来的。

假如线程A正在执行到某个地方,突然失去了CPU的执行权,切换到线程B了,然后当线程A再获得CPU执行权的时候,怎么能继续执行呢?这就是需要在线程中维护一个变量,记录线程执行到的位置。

如果线程正在执行Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址;

如果正在执行的是Native方法,则这个计数器为空。

The Java Virtual Machine can support many threads of execution at once (JLS §17). Each Java Virtual Machine thread has its own pc (program counter) register. At any point, each Java Virtual Machine thread is executing the code of a single method, namely the current method (§2.6) for that thread. If that method is not native, the pc register contains the address of the Java Virtual Machine instruction currently being executed. If the method currently being executed by the thread is native, the value of the Java Virtual Machine's pc register is undefined. The Java Virtual Machine's pc register is wide enough to hold a returnAddress or a native pointer on the specific platform.

2.3.3.5 Native Method Stacks(本地方法栈)

如果当前线程执行的方法是Native类型的,这些方法就会在本地方法栈中执行。

那如果在Java方法执行的时候调用native的方法呢?

image.png

栈指向堆

如果在栈帧中有一个变量,类型为引用类型,比如Object obj=new Object(),这时候就是典型的栈中元
素指向堆中的对象。
image.png

2.3.4.2 方法区指向堆

方法区中会存放静态变量,常量等数据。如果是下面这种情况,就是典型的方法区中元素指向堆中的对
象。

private static Object obj=new Object();

image.png

2.3.4.3 堆指向方法区

What?堆还能指向方法区?
注意,方法区中会包含类的信息,堆中会有对象,那怎么知道对象是哪个类创建的呢?

image.png

思考

一个对象怎么知道它是由哪个类创建出来的?怎么记录?这就需要了解一个Java对象的具体信息咯。

下节课给大家详细讲解对象的内存布局

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

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

相关文章

输入框长度在XSS测试中如何绕过字符长度限制

大家好,这是我编写的第一篇文章,之所以会分享这个故事,是因为我花了几个晚上的时间,终于找到了解决某个问题的方法。故事如下: 几个月前,我被邀请参加一个非公共的漏洞悬赏项目,在初期发现了一些…

汽车行业案例 | 联合汽车电子全新质量问题管理平台上线,燕千云助力汽车电子领军者实现数字化质量管理

据权威调研机构显示,2022年中国智能电动汽车的销量已占新能源汽车的52%以上。到2025年,在新能源汽车50%的汽车出行市场渗透率的基础上,智能电动汽车的销量将超1220万辆,占新能源汽车的80.1%。在技术进步和产业变革快速推进的背景下…

curl命令详解及设置代理服务器

目录 概述 Linux Curl命令详解 Curl命令参数 Curl模仿浏览器命令 Curl模仿浏览器详解 模仿浏览器 Curl伪造refer命令 Curl伪造refer详解 伪造refer Curl下载文件或网页详解 Curl下载进度条命令 Curl下载进度条详解 Curl断点续传命令 Curl断点续传详解 断点续传 …

Kubernetes客户端认证—— 基于CA证书的双向认证方式

1、Kubernetes 认证方式 Kubernetes集群的访问权限控制由API Server负责,API Server的访问权限控制由身份验证(Authentication)、授权(Authorization)和准入控制(Admission control)三个步骤组成,这个三个步骤是按序进行的&#x…

Docker 安装 MySQL5.6

方法一、docker pull mysql 查找Docker Hub上的mysql镜像 #docker search mysql 这里我们拉取官方的镜像,标签为5.6 #docker pull mysql:5.6 (第一次启动Docker-MySql主要是查看Docker里面MySQL的默认配置,数据位置,日志位置,配…

Flink非对齐checkpoint原理(Flink Unaligned Checkpoint)

Flink非对齐checkpoint原理(Flink Unaligned Checkpoint) 为什么提出Unaligned Checkpoint(UC)? 因为反压严重时会导致Checkpoint失败,可能导致如下问题 恢复时间长-服务效率低非幂等和非事务会导致数据…

企业电子招投标采购系统源码之电子招投标的组成 tbms

功能模块: 待办消息,招标公告,中标公告,信息发布 描述: 全过程数字化采购管理,打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&…

当我们在谈Web3时,其实谈的是什么?

当我们在谈Web3时,其实谈的是什么?虽然这个问题看似简单,但是Web3的定义却十分复杂。在这篇文章中,我们将尝试用简单易懂的语言来解答这个问题,并深入探讨Web3对未来的影响。 首先,Web3是什么?简…

通讯软件013——分分钟学会Kepware OPC AE Server仿真配置

本文介绍如何使用Kepware软件仿真OPC AE Server配置。相关软件可登录网信智汇(wangxinzhihui)下载。 1、创建1个数据源:本案例采用“Graybox.Simulator.1”作为数据源。连接OPC Server数据源“Graybox.Simulator.1”。 右键点击“连通性”&am…

SpringBoot复习:(14)容器是怎么创建出来的?

在SpringApplication类的run方法。低版本和高版本的SpringBoot实现有区别。 低版本: run方法调用了createApplicationContext createApplicationContext代码如下: 它会根据contextClass来实例化一个容器然后返回. ¥¥&#xffe…

【设计模式——学习笔记】23种设计模式——命令模式Command(原理讲解+应用场景介绍+案例介绍+Java代码实现)

案例引入 有一套智能家电,其中有照明灯、风扇、冰箱、洗衣机,这些智能家电来自不同的厂家,我们不想针对每一种家电都安装一个手机App来分别控制,希望只要一个app就可以控制全部智能家电要实现一个app控制所有智能家电的需要&…

小程序开发趋势:探索人工智能在小程序中的应用

第一章:引言 小程序开发近年来取得了快速的发展,成为了移动应用开发的重要一环。随着人工智能技术的飞速发展,越来越多的企业开始探索如何将人工智能应用于小程序开发中,为用户提供更智能、便捷的服务。本文将带您一起探索人工智能…

YOLOv8+DeepSORT多目标跟踪(行人车辆计数与越界识别)视频教程

课程链接:https://edu.csdn.net/course/detail/38870 本课程使用YOLOv8和DeepSORT对视频中的行人、车辆做多目标跟踪计数与越界识别,开展YOLOv8目标检测和DeepSORT多目标跟踪强强联手的应用。 课程分别在Windows和Ubuntu系统上做项目演示,并…

基于SpringBoot+Vue的在线考试系统设计与实现(源码+LW+部署文档等)

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

【样式】默认都不选

html <view class"u-flex u-m-t-32 u-m-b-24 u-f-s-24"><view class"u-flex" click"navFun(1)"><text>佣金率</text><image src"/static/img/pai1.png" mode"" class"u-w-28 u-h-32"…

RabbitMQ 教程 | 第7章 RabbitMQ 运维

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

P7883 平面最近点对(加强加强版)

题目 思路 一眼二分&#xff0c;把平面分成两部分&#xff0c;查左右两边&#xff0c;但是还有可能跨中间的线&#xff0c;所以这个也得判 代码 #include<bits/stdc.h> using namespace std; #define int long long const int maxn4e510; pair<int,int> a[maxn]…

Java版Spring Cloud+Spring Boot+Mybatis+uniapp知识付费平台讲解+免费搭建 qt

&#xfeff;Java版知识付费源码 Spring CloudSpring BootMybatisuniapp前后端分离实现知识付费平台 提供职业教育、企业培训、知识付费系统搭建服务。系统功能包含&#xff1a;录播课、直播课、题库、营销、公司组织架构、员工入职培训等。 提供私有化部署&#xff0c;免费售…

亚马逊云科技HPC解决方案,帮助浙江大学实现成本和科研任务的双丰收

浙江大学土壤学科是朱祖祥院士等几代土壤科学家共同创建的A国家重点学科&#xff0c;整体实力雄厚&#xff0c;优势特色明显&#xff0c;总体水平居国内前列。在亚马逊云科技科研创新支持计划&#xff08;Amazon Web Services Cloud Credits for Research&#xff09;的多次支持…

发掘JavaScript潜力:掌握高级技巧,成为JavaScript编程大师!

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! &#x1f4da; 前言 众所周知&#xff0c;JavaScript 是一种非常流行&#x1f525;的编程语言&#xff0c;它已经成为了网…