篇一:JAVA运行时内存模型

jvm运行时数据区& Java 内存模型 JMM 是一种抽象规范(JSR-133),它屏蔽了底层硬件(寄存器、缓存、内存)和操作系统(编译器优化、处理器重排序)的差异,保证 Java 程序在各种平台下对内存的访问都能达到一致的效果。Happens-Before 原则:JMM 定义的一系列天然的先行发生关系(如:启动线程的操作先于线程内的任何操作)。与虚拟机栈类似,区别在于它是为 Native 方法(JNI,如 C++ 编写的底层库)服务的。问题:线程 A 修改了变量,线程 B 无法立即看到,因为线程 A 改的是自己缓存里的副本。 阅读详情

参考资料:《深入理解JAVA虚拟机》

JVM 简介:A为java程序,jre包含了JVM,建立在操作系统之上,应用程序之下

运行时数据区域

  

程序计数器

是一块较小的内存空间,可以看做当前线程所执行的字节码的行号指示器。通过改变这个计数器的值来获取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要以来这个计数器来完成。

JAVA虚拟机的多线程是通过线程轮流切换并分配处理器执行时间方式实现。在任何一个确定的时刻,一个处理器只会执行一条线程指令。因此,为了切换线程后恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各线程之间计数器互不影响,独立存储,这类内存区域称为“线程私有”内存。

如果线程执行的是JAVA方法,这个计数器记录的是正在执行的虚拟机字节码指令地址。如果是Native方法,这个计数器为空,这个内存区域是唯一虚拟机规范中没有规定任何OutOfMemoryError的区域。

虚拟机栈

线程私有,虚拟机栈的生命周期和线程的生命周期相同。虚拟机栈描述java方法执行时的内存模型:每个方法在执行的时候都会创建一个栈帧用户存储局部变量表、操作栈、动态连接和方法出口等信息。每个方法的执行过程就对应着一个栈帧从入栈到出栈的过程。

局部变量表存放各种基本数据类型(int、byte、char等)、对象引用(reference类型)、returnAddress类型(指向一条字节码指令地址)。

局部变量表所需要的空间在编译期间完成分配,进入方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的。这里规定了两种异常情况:如果线程请求栈深度大于虚拟机允许的深度抛出StackOverFlowError;如果虚拟机允许动态扩展空间,当扩展无法申请到足够的内存则会抛出OutOfMemoryError。

本地方法栈

和虚拟机栈类似,虚拟机栈执行java方法,本地方法栈为虚拟机使用到的Native方法服务。

Java 堆

JAVA堆是被线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。所有对象实例以及数组都要在对上分配。

java堆是垃圾回收管理的主要区域。很多时候也被称为“GC堆”。java堆可以处于物理上不连续的内存空间,只要逻辑上连续即可。

方法区

线程共享的内存区域,存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。也称为“非堆”。垃圾回收器在这个区域很少出现,但并不是非数据进入方法区之后就如永久代名称一样“永久”存在。这个区域回收的目标主要针对常量池的回收和对类型的卸载。

运行时常量池

属于方法区的一部分。Class文件中除了方法区所说的信息外还有一个常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容在类加载后存放到方法区的运行时常量池中。

Java虚拟机对Class文件的每一个部分都有严格的格式规定,每一个字节用于存储哪种数据都必须符合规范要求,这样才会被虚拟机认可、装载和执行。但是对于运行时常量池,Java虚拟机没有任何细节要求。一般情况,除了保存Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。

运行时常量池具有动态性,Java语言并不要求常量一定只能在编译时产生,在运行期间也可以将新的常量放入到常量池中,利用得比较多的是String类的intern() 方法。

对象访问

在java中,对象访问是如何进行的?

对象访问无处不在,最简单的行为也会涉及到java栈、java堆、方法区这三个最重要的内存区域。

如:Object obj = new Object();

Object obj 声明变量会反映到java栈的本地变量表中,作为一个reference类型数据。new Object定义会反映到java堆中,形成一块存储了Object类型的所有实例数据值的结构化内存。

reference类型在java虚拟机规范里面只规定了一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位。主流的访问方式有两种:使用句柄和直接指针。

  • 使用句柄访问,java堆中会划分出一块内存作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和对象类型数据各自的具体地址信息。如图所示

 直接指针访问方式。java堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,reference中直接存储的就是对象地址。如图所示

这两种方式各有优势,使用句柄方式最大好处就是reference中存储的是稳定的句柄地址,在对象被移动的时候(垃圾回收时,移动对象十分普遍)只会改变句柄中的实例数据指针,而reference本身不需要被修改。

使用直接指针方式访问的好处就是速度更快,节省了一次指针定位的时间开销,由于对象访问非常频繁,所以这种开销积少成多也是很可观的。

垃圾收集器与内存分配策略

可回收对象

引用计数算法

给对象添加一个引用计数器,每当有一个地方引用它时,计数器+1,失效时则-1.任何时刻计数器都为0的对象就是不可能再被使用的。则回收它。

优点:实现简单,判断效率高。

缺点:无法解决循环引用问题。

根搜索算法

通过一些列名为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则,证明此对象是不可用的。

java中GC Roots对象包括下面几种:

  • 虚拟机栈,栈帧中的本地变量表中的引用对象

  • 方法区中的静态属性引用对象

  • 方法区中的常量引用对象

  • 本地方法栈中JNI的引用对象

引用

JDK 1.2之后对引用概念进行了扩充分为:强引用、软引用、弱引用、虚引用。

  • 强引用:在程序代码中普遍存在,类似Object obj = new Object()这种引用,只要强引用在,垃圾回收器就永远不会回收

  • 软引用:用来描述一些还有用,但是非必需的对象。弱引用关联的对象在系统将要发生内存溢出之前,会将这些对象列入回收范围并进行二次回收

  • 弱引用:描述非必需的对象,它的强度比软引用更弱,弱引用的对象只能生存到下一次GC发生之前

  • 虚引用:最弱的引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成印象,也无法通过虚引用来获取对象实例。使用虚引用的唯一目的就是回收的时候会受到系统通知

方法区回收

方法区回收相对java堆回收来说效率低。

主要回收两部分内容:废弃常量和无用类。回收废弃常量比如一个字符串“abc”进入常量池中,但是当前系统没有任何一个String对象引用这个“abc”,也没有其他地方引用这个字面量,这就是一个废弃常量。

判断“无用类”的方式,必须同时满足:

  • 该类所有的实例都被回收

  • 加载该类的ClassLoader已被回收

  • 该类对应的java.lang.Class对象没有任何地方引用,也无法在任何地方通过反射访问该类的方法

虚拟机可以对满足以上三个条件的类进行回收。

垃圾回收算法

标记-清除算法

最基础的手机算法,分为标记和清除两个阶段。首先标记处所有需要回收的对象,在标记完成之后统一进行回收。

缺点:

  • 效率问题,标记和清除过程效率都不高

  • 空间问题,标记清除之后会产生大量不连续的内存碎片。

复制算法

为了解决效率问题,诞生了复制算法。

它可以将可用内存按照容量划分为大小相等的两块,每次只使用其中一块。当这块的内存使用完,就将还存活着的独享复制到另外一块上面,然后把使用过的内容空间一次清理掉。

缺点:

  • 内存缩小为原来的一半

标记-整理算法

和标记-清除算法类似,第一个步骤标记需要回收的内存空间,然后将所有存活的对象向一端移动,使其连续避免造成内存碎片。然后直接清理掉端外内存空间。

分代收集算法

根据对象的存货周期的不同将内存划分为几块。一般分为新生代和老年代,这样就可以根据不同年代的特点采用最合适的收集算法。

篇二:类文件结构

面试回答,JVM内存模型/内存空间:运行时数据区 发布于个人公众号,打开微信,搜索MelodyJerry即可 本文由作者原文 [JVM|内存模型] Java虚拟机的内存模型?也就这7个而已 修改而来,可点击左下角阅读原文。 JVM内存模型/内存空间 Java虚拟机JVM运行起来,就会给内存划分空间,这块空间成为运行时数据区。 运行时数据区主要划分为以下 6个 : ① 程序计数器 (Program Counter Register) 一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器 线程私有的内存 值得注意的是:《Java虚拟机. 阅读详情

相关推荐

第十六届蓝桥杯大赛软件赛(编程类)知识点大纲

难度:[1-3]难度:[1-5]难度:[1-3]难度:[2-5]难度:[1-5]

Future_yzx的博客 4113

JVM(Java虚拟机模型、Java运行时数据区模型)

JVM

.鞭指云端.的技术博客 526

从Axure转Figma?这篇编组、缩放、圆角、评论的对比指南帮你无缝切换

本文为资深Axure设计师提供了向Figma无缝迁移的实战指南。文章深度对比了编组、缩放、圆角、评论等核心操作,重点解析了Figma独特的自动布局、组件系统和实时协作功能,旨在帮助用户快速适应新工具,实现设计思维与工作效率的跃迁。

tomato的博客 850

Java篇| JVM模型

对JVM的机制模型进行图文表述。理解JVM一些基本的运行原理。 主要以JDK8分析,运行时数据区工作情况。GC回收机制等。

totomiz的博客 305

Intel Arc显卡玩《三角洲行动》报错?手把手教你修改注册表跳过验证

本文针对Intel Arc显卡用户在运行《三角洲行动》时遇到的驱动验证报错问题,提供了详细的解决方案。通过安全修改Windows注册表,添加特定键值以跳过游戏驱动兼容性验证,并结合游戏内图形设置与Intel驱动面板的优化建议,旨在帮助玩家顺利进入游戏并提升游戏帧率与运行稳定性。

weixin_29310605的博客 696

保姆级教程:用ArcGIS Pro搞定云南30米分辨率DEM地形图(附数据下载与配色方案)

本文提供了一份详细的ArcGIS Pro教程,指导用户如何制作云南30米分辨率DEM地形图。从数据下载、预处理到镶嵌与质量控制,再到地形分析与可视化,全流程覆盖云南复杂地形的处理要点。特别包含数据下载链接、配色方案及常见问题解决方案,适合地理信息分析新手和专业人士。

weixin_30467199的博客 309

Java内存区域(运行时数据区域)和内存模型(JMM)

Java运行时数据区域 和 内存模型(JMM)Java运行时数据区域程序计数器Java虚拟机栈1. 局部变量表2. 操作栈3. 动态链接4.方法返回地址本地方法栈Java堆方法区运行时常量池直接内存Java内存模型计算机高速缓存和缓存一致性JVM主内存与工作内存重排序和happens-before规则happens-beforevolatile关键字 前言 Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分。而内存模型(Java Memory Mo

小驴程序源 1236

用 Python 和 uiautomation 实现微信批量发送

思路是这样,将要发送的人员名单(包括称呼)以及发送内容都维护到Excel里,程序运行时读取Excel里内容,自动搜索人员姓名(微信昵称或备注名),填入要发送的内容,拼接上称呼(如果需要的话)自动点击发送,这样轮巡直至名单人员全部发送完成。、

jankingdom的专栏 1471

Java内存模型(JMM)

全称Java Memory Model(JMM)。我们都知道创建一个对象需要分配内存空间并且在不需要该对象时及时回收内存。仔细回想,我们似乎并没有为我们new创建的每一个对象来编写过分配内存空间及回收内存相应的代码。但对象仍然很好的被回收了,原因是Java程序将内存的控制权交给了JVM虚拟机,所以在不了解虚拟机的内存机制的情况下,如果出现了内存泄漏与溢出,那么排查错误将是一个非常艰巨的任务。要想知道JVM如何规划内存,首先要知道数据在内存中如何储存,当然不同类型的数据在内存中所存储的区域也不同。

w259149的博客 6324

DSP TMS320F280049之CCS工程的建立(库函数版)

TMS320F280049 DSP是TI最新出的一款C2000系列的DSP,主频为100MHZ,功能较为强大,具有较多的片上模拟外设。这一节主要讲述如何新建F280049的CCS工程。 Step1.下载文件: 下载C2000Ware软件并安装。下载地址如下: http://www.ti.com.cn/tool/cn/C2000WARE?keyMatch=C2000Ware%2...

fanxianyan1993的博客 1万+

AUTOSAR从入门到精通-【应用实战篇】车载HMI-ADAS

ADAS是高级驾驶辅助系统(Advanced Driving Assistance System)简称ADAS。ADAS高级驾驶辅助系统是利用安装于车上的各式各样的传感器, 在第一时间收集车内外的环境数据, 进行静、动态物体的辨识、侦测与追踪等技术上的处理, 从而能够让驾驶者在最快的时间察觉可能发生的危险, 以引起注意和提高安全性的主动安全技术。

lin_xiu的博客 1435

Java运行时内存管理

Java运行时内存管理

Crazy程序猿 981

专栏三:解析spatialCNV的使用

文章Spatially resolved clonal copy number alterations in benign and malignant tissue发在natur

m0_58549466的博客 1252

【Java 开发日记】我们来说一说 JVM 的内存模型

本文系统介绍了JVM内存结构(运行时数据区)的组成及其特性。主要内容包括:程序计数器(线程私有,记录执行位置)、Java虚拟机栈(存储方法调用栈帧)、Java堆(存放对象实例,GC主要区域)、方法区(存储类信息等,JDK8后改为元空间实现)和运行时常量池(存储字面量和符号引用)。此外还介绍了直接内存(NIO使用的堆外内存)。文章对比了各区域的线程共享性、存储内容和可能的内存异常(OOM/SOF),并区分了JVM内存结构与Java内存模型的不同概念。这些知识是理解Java程序运行机制和性能调优的基础。

纵有疾风起 人生不言弃 2152

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java内存模型和 JVM 内存运行时

当我们提到 Java 的内存模型的时候通常会想到 JVM 运行时候的数据区域,比如包括线程私有的堆,方法区,线程共享的有本地方法栈,虚拟机栈,程序计数器。Java程序启动后,就会初始化这些内存的数据。但是这就是 Java 的内存模型了吗?Java的内存模型(Java Memory Model,JMM)是Java虚拟机(JVM)规范中定义的一种抽象概念,用于描述Java程序中各种变量的存储方式、访问规则以及线程之间的交互关系。

欲望以提升热忱 毅力以磨平高山 1538

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java运行时内存模型

Android原生开发以Java为主,而Java程序都是运行在Java虚拟机(JVM)之上的且内存全权交给虚拟机去管理,那虚拟机的运行时内存模型是如何构成的?堆和栈,相信很多人都能脱口而出,但这只是对内存粗略的一种划分,其中”堆”对应内存模型的Java堆;”栈”则是指虚拟机栈,但是实际上Java运行时内存模型比这复杂多了,在SUN制定的Java虚拟机规范中,运行时内存模型,分为线程私有和共享数据区...

u011339364的专栏 704

思考:Java内存模型和硬件内存模型

前一阵在看volatile的原理,看到内存屏障和缓存一致性,发现再往底层挖就挖到了硬件和Java内存模型。这一块是自己似懂非懂的知识区,我一般称之为知识混沌区。因此整理这一篇文章。什么是内存模型(Memory Model)呢?它是系统和程序员之间的规范,它规定了存储器访问的行为,并影响到了性能。并且,Memory Model有多层,处理器规定、编译器规定、高级语。

bigben 1099

JAVA运行时内存模型

JAVA运行时内存模型 对于部分Java程序员来说,Java内存分为堆和栈,这其实是非常粗略的一种划分,这里的堆对应内存模型中Java堆,栈对应内存模型中虚拟机栈,这是不全面的认识。实际上,运行时内存模型有五大区域,分为线程私有和线程共享两大类。其中线程私有的数据区包含程序计数器、虚拟机栈、本地方法栈,线程共享的数据区包含堆、方法区,注意在方法区中有一个常量池。 线程私有 程序计数器: 记录...

T_chuxin的博客 439

区分什么是Java内存模型(JMM)和 JVM运行时数据区

Java的内存区域和内存模型是不一样的东西,内存区域是指JVM 运行时将数据分区域存储,强调对内存空间的划分。而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之间的抽象关系,即 JMM 定义了 JVM 在计算机内存(RAM)中的工作方式,如果我们要想深入了解Java并发编程,就要先理解好Java内存模型。

初心不改 1521

java 运行时内存模型_JVM内存模型与运行时数据区域的详解(图文)

本篇文章给大家带来的内容是关于JVM内存模型与运行时数据区域的详解(图文),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。一、java内存模型java定义内存模型的目的是:为了屏蔽各种硬件和操作系统的内存访问之间的差异。java内存模型规定了所有的变量都存储在主内存中,每条线程拥有自己的工作内存,工作内存保存了主内存中变量的副本。线程对变量操作只能在工作内存中进行,不能直接读写主内...

weixin_42347873的博客 335

JAVA学习笔记-JAVA内存模型和JVM运行时数据区

JAVA学习笔记-JAVA内存模型和JVM运行时数据区前言JVM运行时数据区JVM运行时数据区和JAVA内存模型的区别JAVA内存模型为什么要有JAVA内存模型 前言 在学习Java的时候,会去查看一些博客,想深入了解或者拓展一些知识,但是大部分都似是而非,虽然标题是Java内存模型,但是里面的内容确实运行时数据区,所以想自己写一篇相关的博客。 JVM运行时数据区 JVM运行时数据区可以分为两部分...

renple的博客 298

深入理解java虚拟机(一)JVM内存模型

文章目录前言一、JVM内存模型1.程序计数器2.Java虚拟机栈3.本地方法栈4.Java堆5.方法区6.运行时常量池7.直接内存二、HotSpot虚拟机对象探秘1.对象的创建2.对象的内存布局3.对象的访问定位结尾 前言 对于从事C、 C++程序开发的开发人员来说,在内存管理领域,他们既是拥有最高权力的“皇帝”,又是从事最基础工作的劳动人民——既拥有每一个对象的“所有权”,又担负着每一个对象生命从开始到终结的维护责任。 对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每一个new操作

少说,多做 1万+

java内存模型及运行时数据区

java中内存模型划分及Runtime Data Area(运行时数据区) 在Java中我们常常说到的内存管理就是针对运行时数据区进行管理(如何分配和回收内存空间)。 VM中的运行时数据区应该包括(1,2,3,4,5)。在JVM规范中虽然规定了程序在执行期间运行时数据区应该包括这几部分, 但是至于具体如何实现并没有做出规定,不同的虚拟机厂商可以有不同的实现方式。 1、程序计数器(Program ...

weixin_39435629的博客 314

基础篇:JVM运行时内存布局

JAVA运行内存和JAVA内存模型

潜行前行的专栏 3964

Java内存模型(JMM)​和JVM内存模型(运行时数据区)​

Java内存模型(JMM)​和JVM内存模型(运行时数据区)​。

qw2869534823的博客 590

Java内存模型与JVM运行时数据区的区别

Java内存模型是Java语言在多线程并发情况下对于共享变量读写(实际是共享变量对应的内存操作)的规范,主要是为了解决多线程可见性、原子性的问题,解决共享变量的多线程操作冲突问题。

weixin_74412978的博客 645
上一篇: 【无标题】JVM学习笔记
下一篇: 篇二:类文件结构
泡泡s
博客等级 码龄6年 1粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值