jvm专题 之 内存模型

文章目录

  • 前言
  • 一个java对象的运行过程
  • jvm内存分布
  • 程序的基本运行程序
    • 对象
      • 什么是对象
      • 对象的创建
        • 一、类加载检查
        • 二、对象内存分配
        • 三、初始化零值
        • 四、设置对象头
        • 五、执行初始化方法
      • 对象的访问定位
    • 对象与类的关系
    • 由类创建对象的顺序
  • 对象的创建

前言

  • 一个程序需要运行,需要在内存中开辟一块空间
  • 类是构建对象的模板,只有类加载到内存中才能创建对象

一个java对象的运行过程

在这里插入图片描述

1、我们自己创建一个Test类,功能只有一个:System.out.println(“hello world”);
2、然后通过终端运行 javac Test.java,会将Test类编译成二进制字节码文件Test.class
3、然后我们继续运行 java Test.class,于是会打印出“hello world”。
4、控制着程序的执行流程的是虚拟机栈
( 打印的过程就是在内存中进行的)

jvm内存分布

  • 由上边图可以看到,jvm主要分为五个区域。我们可以分为两大类:

    线程独享:程序计数器、本地方法栈、虚拟机栈
    线程共享:堆、方法区

  • 每个区域主要的职责,参看上图就可以了,这里不多数
    (各位读者,如果有了解本地方法栈的,欢迎留言哦)

程序的基本运行程序

在java中,万物皆可对象。那么,什么是对象呢,对象与类又是什么关系呢?

对象

什么是对象

  • 对象是堆内的一块内存空间,是由类构建出来的

对象的创建

一、类加载检查
  • 检查 能否在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否被加载、解析和初始化
    • 如果类已经加载过了,会在方法区有一个类的class对象
    • 如果类没有加载过,需要先执行类的加载流程
二、对象内存分配
  • 类加载检查通过 后,接下来虚拟机为新生对象分配内存(大小在类加载完成后便可以完全确定)

    • 分配内存的方法
      • 指针碰撞法(假设java中内存是绝对规整的)(带Compact的收集器,如Serial ParkNew)
      • 空闲列表法(java堆中内存并不规整)(基于Mark-Sweep算法的收集器,如CMS)
    • 多线程时如何保证划分的空间可用?

      (1) 使用CAS配上失败重试的方式保证更新操作的原子性
      (2)本地线程分配缓冲TLAB:线程开启时,虚拟机为每个线程分配一块较大的空间,然后线程内部创建对象时从自己的空间分配
      (每个线程在java堆中预先分配内存TLAB,可以通过-XX:+/-UseTLAB参数来设定)

三、初始化零值

给实例对象的成员变量赋零值,如int型为0,引用类型为null。
这样在没有赋值的情况下,对象也可以使用

四、设置对象头
  • 对象头
    • Mark Word:HashCode、GC分代年龄、持有锁的状态、偏向线程ID、偏向时间戳
    • 类型指针:指向类元数据的指针(虚拟机通过这个指针来确定这个对象时哪个类的实例)
  • 实例数据:对象真正存储的有效信息(相同的宽度总是被分配到一起)
  • 对齐填充:jvm要求对象的大小必须是8字节的整数倍
五、执行初始化方法

如 构造方法

对象的访问定位

  • 直接指针:对象实例数据 + 对象类型数据的指针
    • 特点:java堆中存储 对象实例数据+对象类型数据的指针 放在一起
    • 优点:访问速度快
  • 句柄指针:(句柄池中)对象实例数据的指针 + 对象类型数据的指针;对象实例数据在堆中额外的位置
    • 特点:java堆中需要划分出一部分来作为句柄池,
    • 好处:有稳定的句柄池,在对象被移动时只会改变句柄池中的指针
    • 缺点:相比直接指针,访问速度慢

对象与类的关系

  • 类是构建对象的模板,类中有什么,对象当中有什么。

由类创建对象的顺序

  • 我们先来一个Person类,然后再来一个Test类用来测试,一起来看一下顺序

  • 代码

    public class Person {String name;Integer age;Character sex;public static void breath(){System.out.println("会呼吸");}public void speek(){System.out.println("可以说话");}
    }
    
    public class Test {public static void main(String[] args) {Person person1 = new Person();person1.name = "Lucy";person1.age = 20;person1.sex = 'F';System.out.println(person1.name+",年龄为:"+person1.age+",性别是:"+person1.sex);person1.breath();    // 也可以Person.breath();person1.speek();// person2是为了后续的内容讲解,此处先不用关注Person person2 = new Person();person2.name = "Lucy";person2.age = 20;person2.sex = 'F';person2.breath();person2.speek();}
    }
    

    备注:person2是为了对比,下边内容讲解会先忽略这里,只看person1

  • 内存图
    在这里插入图片描述

    执行顺序:
    1、加载Test类信息到方法区中
    2、main()方法入栈
    3、加载Person类信息到方法区
    4、给对象person1的name赋值,name为String类型,person1对象中name指向的是一个引用地址,数据存放在方法区的字符串常量池中
    5、给对象person1的age赋值,age为Integer类型,当age取值为[-128,127]时,age指向的是数组中的某一个。如果超出范围,会创建新的Integer对象
    6、给对象的sex赋值,在堆中创建一个对象
    7、调用breath()方法
    8、调用speek()方法

  • 多说两句(以上边的person1和person2来比对)

    • 如果age取值在[-128,127]内,多个对象指向的是同一内存空间
      System.out.println(person1.age == person2.age);
      -------------
      true
      
    • 如果age取值不在[-128,127]之间,那么不同的对象的age需要在堆中额外创建对象
      person1.age = 200;
      person2.age = 200;
      System.out.println(person1.age == person2.age);
      --------运行结果---------
      false
      
    • 对于Character类,只要值相等,那么多个对象指向的是同一空间地址
      System.out.println(person1.sex == person2.sex);
      --------运行结果---------
      true
      

对象的创建

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

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

相关文章

JNI实现Java调用C++函数

1. 测试环境 操作系统:win10JDK版本:JDK11 安装教程gcc版本:8.1.0 2. 声明native方法 // HelloJNI.java public class HelloJNI {// 输出Hello JNI from CPP. private native static void sayHello();// 实现两个整数相加private native s…

Android手机投屏方案实现方式对比

文章目录 1.概述2.术语解释2.1 miracast2.2 scrcpy2.4 Wifi Direct2.5 app_process 3.技术实现对比3.1 Miracast3.1.1 Miracast介绍3.1.2 Miracast原理3.1.3 Miracast优缺点分析 3.2 Scrcpy3.2.1 scrcpy 介绍3.2.2 scrcpy的实现原理3.2.3 scrcpy的优缺点分析 3.3 Google cast3.…

【学习笔记】手写 Tomcat 四

目录 一、Read 方法返回 -1 的问题 二、JDBC 优化 1. 创建配置文件 2. 创建工具类 3. 简化 JDBC 的步骤 三、修改密码 优化返回数据 创建修改密码的页面 注意 测试 四、优化响应动态资源 1. 创建 LoginServlet 类 2. 把登录功能的代码放到 LoginServlet 类 3. 创…

Python 算法交易实验89 QTV200日常推进-模式思考

说明 过去几天大A的表现还是比较戏剧化的。 让我想到了: 1 价稳量缩模式。之前很长一段时间都是这种状态,最终还是大爆发了,这个可取。2 周期模式。假设价格是一个周期为T(T可变)的正弦波,所以最终还是回到了几个月前的位置&…

软件测试分类极简理解

基础 - 测试分类(4 种) 1、功能测试(难度:2) 功能测试用于测试软件的功能是否满足需求规格说明书 它验证软件是否能够执行预期的操作 2、性能测试(难度:4) 性能测试用于测试软件…

windows环境Python开发环境搭建指南(附实例源码和讲解教程)

windows环境Python开发环境搭建指南(附实例源码和讲解教程) 本指南将帮助您从零开始搭建一个Python开发环境,包括安装Python、配置环境变量、设置pip镜像源以及创建虚拟环境等步骤。请按照以下步骤操作: 1. 安装Python 首先,请访问Python官…

UE学习篇ContentExample解读------Blueprints Advanced-下

文章目录 总览描述批次阅览2.1 Timeline animation2.2 Actor tracking2.3 Button Trigger using a blueprint interface2.4 Opening door with trigger2.5 Child Blueprints 概念总结致谢: 总览描述 打开关卡后,引入眼帘的就是针对关卡的总体性文字描述&…

【NodeJS】npm、yarn、pnpm当前项目设置国内镜像源

全局设置镜像源,可以参考下这篇文章,还挺详细:《npm、yarn、pnpm 最新国内镜像源设置和常见问题解决》 临时设置镜像源:《npm永久或临时切换源》 有时候可能要同时多个开发项目,又不想修改全局的镜像源(具体场景…自行…

物联网系统中基于IIC通信的数字温度传感器测温方案

01 物联网系统中为什么要使用数字式温度传感器芯片 物联网系统中使用数字式温度传感器芯片的原因主要有以下几点: 高精度与稳定性 高精度测量:数字式温度传感器芯片,如DS18B20,采用芯片集成技术,能够有效抑制外界不…

若依开源系统多数据源整合clickhouse数据库详细步骤

1.添加依赖【pom.xml文件】 <!-- clickhouse数据源依赖--><dependency><groupId>ru.yandex.clickhouse</groupId>

JavaSE之异常专题

JavaSE之异常专题 1. java的异常体系 Java.lang.Throwable&#xff1a;java中的所有错误和异常的父类Error&#xff1a;代表系统级别错误&#xff08;属于严重问题&#xff09;&#xff0c;也就是说系统一旦出现问题&#xff0c;sun公司会把这些问题封装成Error对象给出来Exc…

算法宝典——二分查找算法

1.认识二分查找 二分查找的时间复杂度:O(logN) 二分查找属于算法中耳熟能详的一类&#xff0c;通常的我们会说只有数组有序才可以使用二分查找&#xff0c;不过这种说法并不完全正确&#xff0c;只要数据具有"二段性"就可以使用二分查找&#xff0c;即我们可以找出一…

【零散技术】Odoo PDF 打印问题问题合集

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 Odoo PDF打印 是一个必备功能&#xff0c;但是总会遇到一些奇奇怪怪的问题&#xff0c;此帖仅做记录&#xff0c;方便查阅。 目录 1、样式丢失 2、部分结构丢失 3、没有中文字体 1、样式丢失 这种情况一般是由于 …

ppt压缩有什么简单方法?压缩PPT文件的几种方法

ppt压缩有什么简单方法&#xff1f;许多用户常常面临文件过大的问题&#xff0c;尤其在需要通过电子邮件发送或上传至网络平台时&#xff0c;大文件会带来诸多麻烦。此外&#xff0c;较大的文件可能导致软件响应缓慢&#xff0c;从而影响整体的演示体验。因此&#xff0c;寻找有…

C++ 基础入门-命名空间、c++的输入输出、缺省参数、函数重载、引用、内联函数超详细讲解

这篇文章主要对c的学习做一个基础铺垫&#xff0c;方便后续学习。主要通过示例讲解命名空间、c的输入输出cout\cin&#xff0c;缺省参数、函数重载、引用、内联函数&#xff0c;auto关键字&#xff0c;for循环&#xff0c;nullptr以及涉及到的周边知识&#xff0c;面试题等。为…

机械键盘驱动调光DIY--【DAREU】

1 下载键盘对应的驱动&#xff0c;不要装到C盘 达尔优驱动下载中心 2 驱动更改教程 标准模式 键盘功能 鼠标功能 切换灯光 切换配置文件 多媒体 windows快捷键 禁用 Fn 启动程序 文本功能 光标定位 FN模式 灯光效果设置 注意 宏--自定义功能

RK3568平台(camera篇)tp9930调节亮度色度锐度对比度

一.TP9930说明 1.1说明 TP9930是支持高清传输视频接口(HD)的通用HD/SD视频解码器- TVI)视频、NTSC/PAL CVBS视频以及常见的HD模拟视频格式解码。它集成了4个多标准解码器,可同时对现有的HD模拟格式进行4通道解码。它还可以与任何传统的CVBS相机兼容,以实现向后兼容性。…

spring:spring 中的初始化操作

参考 https://www.jb51.net/program/322735nvy.htmhttps://blog.csdn.net/weixin_40511641/article/details/136843198

Python(七)- 文件操作

目录 文件操作 打开文件 读数据 写数据 关闭文件 文件读写实例 文件写 文件读 读数据类型 备份文件 os模块 目录的具体操作 文件操作 在Python中操作文件记录信息的步骤&#xff1a; &#xff08;1&#xff09;打开文件&#xff0c;或新建一个文件&#xff1b; o…

Qt 项目优化实践方向

目录 1. 使用智能指针2. 避免在全局或静态作用域中使用裸指针3. 利用Qt的对象树进行资源管理4. 延迟加载和按需加载资源5. 合理使用Qt的资源文件&#xff08;qrc&#xff09;6. 监控和调试内存使用7. 优化数据结构8. 减少不必要的资源复制9. 使用缓存机制10. 遵循RAII原则 以下…