Java虚拟机学习笔记(一)——Java内存区域与对象创建

Java虚拟机-内存区域 JVM内存区域概述运行时的数据区域线程私有内存区域程序计数器java虚拟机栈线程公有内存区域本地方法栈java堆方法区直接内存对象访问 概述 c和c++拥有内存管理的权利,而java则是通过虚拟机的自动内存管理机制去管理内存,不需要我们手动进行内存管理。自动内存管理机制不容易出现内存泄露问题,但是一旦出现内存泄露和内存溢出问题,排查问题就需要java虚拟的相关知识。 运行时的数据区域 这里借助一张书里的图片 线程私有内存区域 程序计数器 程序计数器这个概念是在计算机组成原理课程中首次见到。在jvm里,程序 阅读详情

Java内存区域

在这里插入图片描述

1.运行时数据区域

1.1 程序计数器

程序计数器是当前线程执行字节码的行号指示器。字节码解释器工作时需要通过改变这个计数器的值来选取下一条要执行的字节码指令。

多线程执行任务时,由于内核是通过切换来模拟异步操作,所以每条线程都需要一个独立的程序计数器,以便于线程切换后再次回到本线程时可以恢复到上次执行的位置。各条线程之间的计数器互不影响,独立存储,这类内存被称之为线程私有的内存。

1.2 Java虚拟机栈

该内存也是线程私有的,它描述了Java方法执行的内存模型。

在每个方法执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈与出栈的过程。

局部变量表存放了编译时就可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double),对象引用。

局部变量在编译时就已经确定了内存空间,方法运行期间不会改变局部变量表的大小。

当线程请求的栈深度大于虚拟机栈所允许的深度,就会报出StackOverflowError异常。

1.3 本地方法栈

与Java虚拟机栈相似,区别是Java虚拟机栈执行Java方法,而本地方法栈执行虚拟机所使用到的Native方法服务。同时也属于线程私有的。

1.4 Java堆

Java堆是Java虚拟机所管理的内存中最大的一块。

Java堆是所有线程共享的一块内存区域,此内存区域的唯一目的就是存放对象的实例,几乎所有对象的实例都是在这里存放的。

Java堆是垃圾收集器管理的主要区域,很多时候被称为“GC堆”(Garbage Collected Heap),现在的收集器基本采用分代收集算法,所以Java堆可以细分为:新生代和老年代;再细分有Eden空间,FromSurvivor空间,ToSurvivor空间等。

1.5 方法区

属于各个线程共享的内存区域,用于储存已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

运行时常量池属于方法区的一部分。用于存放编译时生成的各种字面量和符号引用。

  • JDK8以前,虚拟机把GC分代设计扩展至方法区,使用永久代来实现方法区,省去了专门为方法区编写内存管理代码。
  • JDK8之后,完全废弃永久代,改为元空间,在本地内存空间实现。将原本在常量池中的StringTable移至堆中。

2.虚拟机对象

2.1 对象的创建

Java虚拟机遇到new指令的时候,首先去检查一下这个指令的参数是否可以在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载,解析和初始化过。如过没有,那就先执行类加载过程。

类加载通过后,进行内存分配。有两种分配方式:第一种被称为指针碰撞。具体实现是所有被使用过的内存放在堆的一边,未被使用过的内存放在另一边。中间有一个指针作为“分界线”,当需要分配内存时,就将指针向未被分配的一边移动与对象大小相等的距离。这种分配方式针对Java堆中的内存是规整的。
另一种分配方式是空闲列表,这种分配方式针对Java堆中的内存空间不是规整的。虚拟机维护一个列表,记录了哪些内存块是可用的,分配的时候在列表上找到一块大小合适的空间分配给对象实例,并更新列表记录。

除了如何划分空间,还应该注意,对象的创建在虚拟机中是非常频繁的行为,即使仅仅只是修改一个指针的位置,在并发的情况下也是不是线程安全的。
要解决这个问题,主要有两种方法:一种是对分配内存的空间进行同步处理,——虚拟机采取的是CAS加上失败重试保证了分配动作的原子性。另一种方式是把内存分配的动作按照线程划分在不同的区域进行,即每个线程在Java堆上预先分配一小块内存,称为本地线程分配缓冲(TLAB),哪一个线程需要分配内存,就在自己的TLAB上分配,只有TLAB用完时,分配新的缓存区时才需要同步锁定。

分配完空间后,虚拟机将分配到的内存空间都初始化为零(不包括对象头),如果使用的TLAB,此操作可以提前至TLAB时。接着将对象进行必要的设置,如属于哪一个类的实例,哈希码…

完成后,从虚拟机的角度看,对象已经产生,但从Java程序的角度来看,对象的创建刚刚开始。接下来执行()方法,将对象按照程序员的意愿进行初始化。

2.2 对象的内存布局

对象在堆内存中的存储分为三大块:对象头,实例数据,对齐填充。

  • 对象头包含两部分信息:第一部分储存对象自身运行时数据,如哈希码,GC年龄分代,锁状态标志等。第二部分是类型指针,即对象指向它类型元数据的指针,Java虚拟机通过这个指针来确定对象是哪个类的实例。但并不是所有虚拟机都保存这个类型指针。

  • 实例数据是存储对象真正有效的信息。

  • 对齐填充没有特别含义,只起到占位符的作用。HotSpot虚拟机自动管理内存要求对象起始地址必须是8字节的整数倍。

2.3 对象访问定位

分为两种方式:

  • 句柄访问在这里插入图片描述
    优点:
    reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针。
  • 直接指针
    在这里插入图片描述
    优点:速度更快,节省一次指针定位的时间开销。

书籍:
《深入理解Java虚拟机》

Masta调用Geometry Modeller(Space Claim)进行根据三维模型快速建模设置方法 masta中调用ANSYS的space claim的设置方法 阅读详情

相关推荐

无感健康监测的未来:毫米波雷达如何重新定义睡眠科技与居家养老

毫米波雷达技术正重新定义无感健康监测,特别是在睡眠科技与居家养老领域。通过精准监测呼吸、心率和体动,无需穿戴设备即可实现临床级精度。结合合宙Air700E开发板,构建了完整的远程看护解决方案,为老年人提供跌倒检测、异常报警等安全保障,同时保护用户隐私。

cake8的博客 569

深入理解Java虚拟机(第三版)-- 虚拟机中的对象

对象的创建 当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程,本书第7章将探讨这部分细节。 在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成 后便可完全确定(如何确定将在2.3.2节中介绍),为对象分配空间...

吴声子夜歌的博客 684

OpenResty无损升级内嵌nginx版本0DAY漏洞

OpenResty无损升级内嵌nginx版本,nginx

qq1071643762的博客 6905

深入理解Java虚拟机-Java内存区域与内存溢出异常

Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来。 文章目录概述运行时数据区域程序计数器(线程私有)Java虚拟机栈(线程私有)局部变量表操作数栈动态链接方法返回地址小结本地方法栈(线程私有)Java堆(全局共享)方法区(全局共享)运行时常量池直接内存HotSpot虚拟机对象探秘对象的创建1.判断对象对应的类是否加载、链接、初始化2.为对...

ThinkWon的博客 2万+

从零到一:Abaqus与Matlab联合仿真的自动化流程构建指南

本文详细介绍了如何构建Abaqus与Matlab联合仿真的自动化流程,涵盖基础架构设计、关键接口技术实现、结果提取与处理技术以及高级参数化优化流程。通过Python脚本作为桥梁,实现数据传递和任务控制,帮助工程师提升仿真效率。特别强调了版本兼容性、异常处理和性能监控等实用技巧。

weixin_29090089的博客 612

WS2812B非标准通信协议:手把手实现精准时序控制

详解WS2812B的精准时序实现原理,剖析其非标准通信协议的关键细节。通过实际操作指导,帮助开发者稳定驱动ws2812b灯带,解决常见时序偏差问题,提升项目显示效果与响应一致性。

weixin_42584586的博客 587

Java对象与JVM(一) Java对象在Java虚拟机中的创建过程

下面我们详细了解Java程序中new一个普通对象时,HotSpot虚拟机是怎么样创建这个对象的,包括5个步骤:相应类加载检查过程、在Java堆中为对象分配内存、分配后内存初始化为零、对对象进行必要的设置、以及执行对象实例方法,最后我们再从JVM指令角度来解释下Java对象创建。

tjiyu的博客 1万+

NVIDIA GR00T SONIC - 人形机器人强化学习全身控制入门教程(一)

SONIC 是一个类人行为基础模型,它为机器人提供了一套从大规模人类动作数据中学习而来的核心运动技能。与为每个动作单独构建控制器不同,SONIC 将动作追踪作为可扩展的训练任务,因此单一套统一策略即可产生自然的全身运动,并支持多种多样的行为。         🎯 主要特点: 🚶 自然的全身运动(行走、爬行、动态动作) 🎮 支持实时 VR 遥操作 🤖 高级规划与交互的基础 📦 即用型 C++ 推理栈

2506_90492529的博客 844

JVM内存区域与HotSpot虚拟机对象详解

一、Java内存区域与内存溢出异常 1.运行时数据空间 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。 线程共享区域:堆,方法区 线程私有区域:虚拟机栈,本地方法区,程序计数器 1.1 线程私有区域 1.1.1 程序计数器 程序计数器是一块比较小的内存空间,它可以看作是当前线程说执行的字节码的行号指示器。为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的区域。 作用:通

一生信仰 7846

基于Playwright和反爬虫规避技术的雪球股票讨论数据采集方案

随着量化投资和社交投资的兴起,雪球作为中国领先的投资社交平台,其用户讨论数据成为研究市场情绪的重要来源。本文将详细介绍如何使用最新的Playwright技术和反爬虫规避策略,构建一个高效、稳定的雪球股票讨论爬虫系统。本文详细介绍了基于Playwright的雪球股票讨论爬虫实现方案,涵盖了从基础配置到高级反爬虫策略的各个方面。AI驱动的反爬虫对抗更智能的请求调度算法区块链技术在数据溯源中的应用联邦学习在数据采集中的运用。

2201_76125261的博客 1012

在zcu102开发板上使用PetaLinux运行Qt程序

请注意,上述步骤只是一个概述,并且可能需要根据特定的开发环境和要求进行适当的调整。如果你是一个初学者或者对于这些领域不太熟悉,建议在尝试之前阅读相关的文档和教程,或者寻求专业人士的帮助。在"Projects"菜单中,选择"Build & Run"选项,并在"Build"步骤中选择正确的工具链。注意:如果Qt程序依赖于其他库文件,需要将这些库文件一起复制到PetaLinux工程的根文件系统目录中,并在Qt程序中正确地配置库文件路径。如果一切顺利,PetaLinux系统将启动,并自动运行Qt程序。

UhxzCombined的博客 698

Java 虚拟机中内存区域介绍 JDK8区别 对象创建 学习笔记

文章目录Java 内存区域详解一 概述 程序执行过程二 运行时数据区域2.1 线程私有2.1.1 程序计数器2.1.2 Java 虚拟机栈2.1.3 本地方法栈2.2 线程共享2.2.1 堆2.2.2 方法区2.2.2.1 方法区和永久代的关系2.2.2.2 常用参数2.2.2.3 为什么要将永久代 (PermGen) 替换为元空间 (MetaSpace) 呢?2.2.3 运行时常量池2.2.4 ...

小鹅鹅的博客 1395

使用MATLAB中的Simulink工具来构建一个微电网系统的仿真平台

微电网是指由分布式电源(如太阳能、风能等)、储能装置、负载以及控制和保护装置组成的局部电力系统。它可以独立于主电网运行,也可以与主电网并联运行。本示例将以一个简单的微电网为例,展示如何利用Simulink进行微电网接入与孤岛运行策略的设计与仿真。分布式电源:模拟太阳能光伏板或风力发电机等分布式电源。储能装置:用于存储多余能量或补充不足能量。负载:模拟实际用电需求。双向变流器:实现直流与交流之间的转换,并支持并网和孤岛模式切换。控制器:负责管理微电网的运行模式,包括并网控制和孤岛控制。

xiaoheshang_123的博客 348

【深入理解Java虚拟机】Java内存区域模型、对象创建过程、常见OOM

本文内容来源于《深入理解Java虚拟机》一书,非常推荐大家去看一下这本书。最近开始看这本书,打算再开一个相关系列,来总结一下这本书中的重要知识点。呃呃呃,说好的那个图片请求框架呢~  不要急哈,因为这个请求框架设计的内容还是比较广的,目前业余时间正在编写当中,弄好了之后就会放上来。在完成之前,咱还是先来学习一下其他知识。1、内存模型java虚拟机在执行java程序的过程中会把它说管理的内存划分为若

开心阳 7768

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

蓝牙模块HM-10手册

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

JVM虚拟机-探究Java内存区域与对象创建过程

JVM虚拟机-探究Java内存区域与对象创建过程 欢迎访问我的个人博客 参考书籍:《深入理解JAVA虚拟机》 这里写目录标题JVM虚拟机-探究Java内存区域与对象创建过程1.概述2.运行时数据区域2.1.程序计数器2.2.Java虚拟机栈2.3.本地方法栈2.4.Java堆2.5.方法区2.6.运行时常量池3.HotSpot虚拟机对象探秘3.1.对象的创建3.2.对象的内存布局3.3.对象的访问定位4.本文知识点思维导图(原图可私信) 1.概述 对于Java程序来说,在虚拟机自动内存管理机制的帮助下,不

weixin_43265151的博客 445

Statistics and Machine Learning Toolbox

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

Java内存区域及对象的创建与回收

从第一天开始学习Java,就需要和JVM打交道,然而对其只知名称,不知内涵。此前一直觉得这块知识晦涩难懂,不想积极地去面对。但是JVM的知识又是每个通往高级Java程序员所必备的,因此正好趁这一阵辞职休息的时间,正面的和JVM刚一下。本文及近期后续JVM相关文章基本都是基于本人阅读的周志明所著《深入理解Java虚拟机-JVM高级特效与最佳实践》一书的读书笔记及心得体会,欢迎留言讨论。 本文主要内容...

Earl_yuan的专栏 663

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

一起学Java虚拟机(一):内存区域和垃圾收集

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

2401_84408814的博客 926

Java 内存区域详解

对于Java程序员来说,在虚拟自动内存管理机制下,不再需要像C/C++程序开发程序员这样为每一个new操作去写对应的delete/free操作,不容易出现内存泄漏和内存溢出问题。正是因为Java程序员把内存控制的权力交给Java虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。

rc1596919047的博客 1410

Java虚拟机一:Java运行时内存区域及对象的创建

一、Java运行时内存区域 首先我们都知道Java的内存管理是由虚拟机管理的,但是如果我们不了解虚拟机的内存管理那么就会造成内存泄露进而导致内存溢出。而且如果不了解内存的分配情况,当我们真的出现了内存泄露或者溢出的时候,我们排查起来那将是异常艰难的,所以了解Java的内存分配是很必要的,对我们的程序的内存优化也是大有利益的。而且,很多人把虚拟机只分为堆内存和栈内存,这种说法是不对的,可是为什么又会...

heng615975867的专栏 165

【JVM-05】Java内存区域(运行时数据区)、对象创建过程、内存布局

Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。JDK 1.8 和之前的版本略有不同。程序计数器虚拟机栈本地方法栈堆方法区直接内存(非运行时数据区的一部分)

Blue_Pepsi_Cola的博客 1390

jvm之java内存区域详解篇guide哥yyds

jvm 一、java内存区域详解 1.运行时数据区域 线程私有的: 虚拟机栈 本地方法栈 程序计数器 线程共享的: 堆 方法区 直接内存(非程序运行时数据区的一部分) 1.1什么是程序计数器 程序计数器是很小的内存空间,可以看作是前线程字节码执行的行号指示器。 作用: 1.字节码解释器通过程序计数器来读取指令,从而实现代码的流程控制,比如:顺序执行、选择、循环、异常处理等。 2.在多线程的情况下,程序计数器记录当前线程的位置,为后面线程切换恢复到正确的位置提供保证。各线程之间的程序计数器互不

m0_63106385的博客 5371

JVM之Java内存区域与Java对象

Java内存区域与Java对象1. Java 内存区域1.1 运行时数据区域1.1.1 程序计数器1.1.2 Java 虚拟机栈1.1.3 本地方法栈1.1.4 Java 堆1.1.5 方法区1.1.6 运行时常量池1.2 直接内存2. Java对象在虚拟机中的创建与访问定位2.1 对象的创建2.2 对象的内存布局2.2.1 对象头2.2.2 实例数据2.2.3 对齐填充2.3 对象的访问定位2.3.1 句柄方式2.3.2 直接指针 1. Java 内存区域     

wang_zhao_的博客 661

Java内存区域与HotSpot虚拟机对象

运行时数据区域程序计数器(Program Counter Register)程序计数器是一块很小的内存空间,可以看做是当前线程所执行的字节码的行号指示器,存储着当前执行的字节码指令,通过改变这里的值来进行指令的调用。 在多线程中每个线程执行的命令都不相同且互不影响,所以程序计数器是线程私有的,这类内存区域“线程私有”的内存。 如果线程正在执行的是一个Java方法,这个计数器存储的是正在执行的虚拟

OverrideRe的博客 685

Java虚拟机(一)——Java内存区域划分

介绍  Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。运行时数据区域  Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器

BridgeGeorge 1835

Java虚拟机(一)- Java内存区域及对象

目录 一、前言 二、对象创建 三、对象定位方式 一、前言 Java虚拟机(JVM)内部定义了程序在运行时需要使用到的内存区域 途中黄色部分为线程共享区域,白色部分为线程私有区域。 1、线程独有的内存区域 (1)PROGRAM COUNTER REGISTER,程序计数器 这块内存区域很小,它是当前线程所执行的字节码的行号指示器,字节码解释器通过改变这个计数器的值来选取下一条需...

qq_33419463的博客 188

Java虚拟机:内存区域分配和对象的创建

首先上一张图:这里主要是看右边的图,这张图描述了JVM中的内存分配区域,其中。我们以这张图为准,介绍JVM内存区域分配中的各个区域。

Tai_Monster的博客 309
下一篇: Java虚拟机学习笔记(二)——类文件结构与字节码指令
<天各一方>
博客等级 码龄6年 17粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值