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

【JVM】运行时数据区与对象的创建流程

4、运行时数据区

4.1、运行时数据区介绍

在这里插入图片描述

运行时数据区也就是JVM在运⾏时产生的数据存放的区域,这块区域就是JVM的内存区域,也称为JVM的内存模型——JMM

  • 堆空间(线程共享):存放new出来的对象

  • 元空间(线程共享):存放类元信息、类的模版、常量池、静态部分

  • 线程栈(线程独享):⽅法的栈帧

  • 本地⽅法区(线程独享):本地⽅法产⽣的数据

  • 程序计数器(线程独享):配合执⾏引擎来执⾏指令

4.2、程序在执行时运行时数据区中的内存变化

⾸先,在程序的.class目录内执行如下命令,查看程序具体的汇编指令

javap -c JVMAnalyze

得到结果:

Compiled from "JVMAnalyze.java"
public class com.qf.jvm.JVMAnalyze {public com.qf.jvm.JVMAnalyze();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnpublic int add();Code:0: bipush        102: istore_13: bipush        205: istore_26: iload_17: iload_28: iadd9: bipush        1011: imul12: istore_313: iload_314: ireturnpublic static void main(java.lang.String[]);Code:0: new           #2                  // class com/qf/jvm/JVMAnalyze3: dup4: invokespecial #3                  // Method "<init>":()V7: astore_18: aload_19: invokevirtual #4                  // Method add:()I12: istore_213: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;16: iload_217: invokevirtual #6                  // Method java/io/PrintStream.println:(I)V20: return
}

通过指令,JMM内存发⽣了如下变化:

在这里插入图片描述

  • 线程栈:执行⼀个方法就会在线程栈中创建⼀个栈帧。

  • 栈帧包含如下四个内容:

    • 局部变量表:存放方法中的局部变量
    • 操作数栈:用来存放方法中要操作的数据
    • 动态链接:存放方法名和方法内容的映射关系,通过方法名找到方法内容
    • 方法出口:记录方法执行完后调用此方法的位置。

5、对象的创建流程

5.1、对象创建流程

在这里插入图片描述

5.2、类加载校验

校验该类是否已被加载。主要是检查常量池中是否存在该类的类元信息。如果没有,则需要进⾏加载。

5.3、分配内存

为对象分配内存。具体的分配策略如下:

  • Bump the Pointer(指针碰撞):如果内存空间的分配是绝对规整的,则JVM记录当前剩余内存的指针,在已用内存分配

  • Free List(空闲列表):如果内存空间的分配不规整,那么JVM会维护⼀个可用内存空间的列表用于分配。

对象并发分配存在的问题:

  • Compare And Swap:自旋分配,如果并发分配失败则重试分配之后的地址

  • Thread Local Allocation Buffer(TLAB):本地线程分配缓冲,JVM为每个线程分配⼀块空间,每个线程在自己的空间中创建对象(jdk8默认使⽤,之前版本需要通过-XX:+UseTLAB开启)

5.4、设置初值

根据数据类型,为对象空间赋初始化值。

5.5、设置对象头

为对象设置对象头信息,对象头信息包含以下内容:类元信息、对象哈希码、对象年龄、锁状态标志等。

  • 对象头中的Mark Work 字段(32位)

在这里插入图片描述

  • 对象头中的类型指针(Klass Pointer)

类型指针用于指向元空间当前类的类元信息。比如调用类中的方法,通过类型指针找到元空间中的该类,再找到相应的方法。

开启指针压缩后,类型指针只用4个字节存储,否则需要8个字节存储

  • 指针压缩

过大的对象地址,会占⽤更大的带宽和增加GC的压力。

对象中指向其他对象所使⽤的指针:8字节被压缩成4字节。 最早的机器是32位,最大支持内存 2的32次方=4G。现在是64位,2的64次⽅可以表示N个T的内存。内存32G即等于2的35次方。如果内存是32G的话,用35位表示内存地址,这样过于浪费。如果把35位的数据,根据算法,压缩成32位的数据(也就是4个字节)。在保存时用4个字节,再使用时使用8个字节。之前用35位保存内存地址,就可以用32位保存。这样8个字节的对象,实际上使用32位来保存,这样64位就能表示2个对象。

如果内存⼤于32G,指针压缩会失效,会强制使用64位来表示对象地址。因此jvm堆内存最好不要大于32G。

Jdk1.6之后默认开启指针压缩,可通过配置jvm参数关闭指针要锁 -XX:-UseCompressedOops

示例代码:

package com.qf.jvm;import org.openjdk.jol.info.ClassLayout;import java.lang.String;/*** 对象指针压缩* @author Thor* @公众号 Java架构栈*/
public class ObjectLengthAnalyze {public static void main(String[] args) {ClassLayout classLayout = ClassLayout.parseInstance(new A());System.out.println(classLayout.toPrintable());}static class A{int num;String name;}
}

关闭指针压缩:

在这里插入图片描述

开启指针压缩:

在这里插入图片描述

5.6、执行init方法

为对象中的属性赋值和执⾏构造方法。

本文章参考B站 千锋教育JVM全套教程(含jvm调优、jvm虚拟机、jvm面试题、jvm源码详解)系统玩转java虚拟机全程干货无废话,仅供个人学习使用,部分内容为本人自己见解,与千锋教育无关。

相关文章:

【JVM】运行时数据区与对象的创建流程

4、运行时数据区 4.1、运行时数据区介绍 运行时数据区也就是JVM在运⾏时产生的数据存放的区域&#xff0c;这块区域就是JVM的内存区域&#xff0c;也称为JVM的内存模型——JMM 堆空间&#xff08;线程共享&#xff09;&#xff1a;存放new出来的对象 元空间&#xff08;线程共…...

flutter- JSON解析框架使用方法json_serializable

对于目前来说&#xff0c;大部分的API网络请求的通讯内容数据格式都是JSON。JSON返回的都是字符串&#xff0c;假如要取到data里面的id&#xff0c;去直接字符串截取肯定是不行的&#xff0c;要通过一定的方式把它解析成Map或者解析成对象&#xff0c;再去处理它。像一些简单的…...

第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)

目录1.搬砖1.题目描述2.输入格式3.输出格式4.样例输入5.样例输出6.数据范围7.原题链接2.解题思路3.Ac_code1.搬砖 1.题目描述 这天&#xff0c;小明在搬砖。 他一共有 nnn 块砖, 他发现第 iii 砖的重量为 wiw_{i}wi​, 价值为 viv_{i}vi​ 。他突然想从这些 砖中选一些出来从…...

Spring Cloud Nacos源码讲解(十)- Nacos服务端服务发现处理

Nacos集群数据同步 ​ 当我们有服务进行注册以后&#xff0c;会写入注册信息同时会触发ClientChangedEvent事件&#xff0c;通过这个事件&#xff0c;就会开始进行Nacos的集群数据同步&#xff0c;当然这其中只有有一个Nacos节点来处理对应的客户端请求&#xff0c;其实这其中…...

C++ 修改程序进程的优先级(Linux,Windows)

文章目录1、Linux1.1 常用命令1.1.1 不占用终端运行和后台运行方式1.1.2 查询进程1.1.3 结束进程1.1.4 优先级命令1.2 C 代码示例1.2.1 代码一1.2.2 代码二2、Windows2.1 简介2.2 函数声明2.3 C 代码示例2.3.1 代码一2.3.2 代码二结语1、Linux 1.1 常用命令 1.1.1 不占用终端…...

同步和异步promise

进程和线程进程&#xff08;厂房&#xff09;&#xff1a;程序的运行环境线程&#xff08;工人&#xff09;&#xff1a;进行运算的东西同步和异步同步&#xff1a;一件事干完才去干下一件事&#xff0c;前面的代码不执行&#xff0c;后面的代码也不执行。同步的代码可能会出现…...

CHATGPT是新的“搜索引擎终结者”吗?百度是否慌了

ChatGPT 以其非凡的自然语言处理 &#xff08;NLP&#xff09; 能力和清晰的响应风靡全球&#xff0c;有望带来一场重大的技术革命。在不知不觉中&#xff0c;叙事转向了ChatGPT与百度的对决&#xff0c;因为来自OpenAI的智能和健谈的聊天机器人已经慢慢获得了“潜在的百度终结…...

力扣-订单最多的客户

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;586. 订单最多的客户二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总…...

MyBatis学习笔记(六) —— MyBatis的各种查询功能

6、MyBatis的各种查询功能 6.1、查询一个实体类对象 SelectMapper.java接口 /*** 根据用户id查询用户信息* param id* return*/ User getUserById(Param("id") int id);SelectMapper.xml <!--User getUserById(Param("id") int id)--> <selec…...

2023年最新详细教程!手把手教你搭建Hexo + GitLab个人博客

文章目录前言一、安装和配置环境1.安装 Git2.安装 Node.js二、新建博客项目1.GitLab配置CI/CD自动化部署1.1 GitLab新建项目1.2 GitLab自建Runners1.2.1 下载gitlab-runner1.2.2 注册Runners1.2.3 安装Runners并启动1.3 添加.gitlab-ci.yml文件2.拉取和推送hexo blog2.1 拉取he…...

centos7安装

centos7安装制作U盘启动盘下载镜像下载 UltralISO制作启动盘使用U盘安装系统修改模式为 UEFI调整BOOT option保存重启进入安装界面安装图形界面安装搜狗输入法制作U盘启动盘 下载镜像 去官网下载镜像&#xff0c;找到 mirrors链接&#xff08;速度快&#xff09; 选择一个中…...

java String类(超详细,含常用方法、面试题,内存图,案例)

String类一、String类的特点二、String 类的常见构造方法三、String常见的面试题1.字符串常量池2.String s "abc"与String s new String("abc")区别3.字符拼接4.常量优化机制四、String常用方法1. 比较字符串内容2. 遍历字符串3.截取字符串4.替换字符串5…...

哈希表以及哈希冲突

目录 哈希表 哈希冲突 1. 冲突发生 2. 比较常见的哈希函数 3. 负载因子调节(重点) 散列表的载荷因子概念 负载因子和冲突率的关系 冲突-解决-闭散列 线性探测 二次探测 冲突-解决-开散列 结尾 我们在前面讲解了TerrMap&#xff08;Set&#xff09;的底层是一个搜索…...

测试——基本概念

概念 测试和调试有以下几点区别&#xff1a; 测试是测试人员进行的工作&#xff0c;调试是开发人员调试是发现并解决问题&#xff0c;测试只是发现问题测试贯穿于整个项目的生命周期&#xff0c;而调试主要在编码阶段 测试人员一般有如下的工作&#xff1a; 需求分析&#x…...

SnowFlake 雪花算法和原理(分布式 id 生成算法)

一、概述 SnowFlake 算法&#xff1a;是 Twitter 开源的分布式 id 生成算法。核心思想&#xff1a;使用一个 64 bit 的 long 型的数字作为全局唯一 id。算法原理最高位是符号位&#xff0c;始终为0&#xff0c;不可用。41位的时间序列&#xff0c;精确到毫秒级&#xff0c;41位…...

【死磕数据库专栏】MySQL对数据库增删改查的基本操作

前言 本文是专栏【死磕数据库专栏】的第二篇文章&#xff0c;主要讲解MySQL语句最常用的增删改查操作。我一直觉得这个世界就是个程序&#xff0c;每天都在执行增删改查。 MySQL 中我们最常用的增删改查&#xff0c;对应SQL语句就是 insert 、delete、update、select&#xf…...

阿里软件测试二面:adb 连接 Android 手机的两种方式,看完你就懂了

前言 随着现在移动端技术的突飞猛进&#xff0c;导致现在市场上&#xff0c;APP 应用数不胜数&#xff0c;那对于测试工程师而言&#xff0c;对于 APP 的测试&#xff0c;那基本就是一个必修课了。 今天&#xff0c;我就来给大家介绍一下&#xff0c;adb 连接 Android 手机的两…...

Docker安装YApi

目录0、Docker 环境准备1、数据库准备 MongoDB2、启动 YAPI3、官网教程0、Docker 环境准备 Docker 容器之间网络互通需要使用 docker network create yapi 创建一个自定义网络 docker network create yapi1、数据库准备 MongoDB YAPI 的数据库是 MongoDB&#xff0c;准备镜像…...

springboot自定义参数解析器

为什么要自定义参数解析器呢&#xff1f; 因为很多项目每次获取用户信息&#xff0c;需要重复从请求头中获取token&#xff0c;用token再去redis或是sql中去拿到存储的计本对象&#xff0c;再将获取到的Json数据&#xff0c;转化为我们需要的对象等代码&#xff0c;作为一名程…...

Python Unittest ddt数据驱动

1、数据驱动介绍&#xff1a; ddt.ddt&#xff08;类装饰器&#xff0c;申明当前类使用ddt框架&#xff09;ddt.data&#xff08;函数装饰器&#xff0c;用于给测试用例传递数据&#xff09;&#xff0c;支持传python所有数据类型&#xff1a;数字&#xff08;int&#xff0c;…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...