重识JVM(2) - JAVA内存模型

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

目录

一、概念和误解

二、疑问

三、计算机的内存模型

3.1. 内存顺序和程序顺序

3.2. SC内存模型

3.3. TSO内存模型

3.4. 其他内存模型

3.5. JAVA内存模型

3.6. volatile实现原理

一、概念和误解

        java内存模型,英文全称为java memory model,简称JMM。网上大部分关于java内存模型的资料都是关于堆栈以及垃圾回收的,事实上java 内存模型与堆栈、垃圾回收没有任何关系。查询维基百科和oracle官网对JMM(java内存模型)的定义:

维基百科原文(点击跳转到原文地址,需要梯子):

The Java memory model describes how threads in the Java programming language interact through memory. Together with the description of single-threaded execution of code, the memory model provides the semantics of the Java programming language.

中文翻译:

java内存模型描述了java编程语言中的多线程(原文用了s,thread复数形式)是怎样与内存交互的。java内存模型与代码的单线程执行情况,一起提供了java编程语言的语义。

oracle官网原文(点击跳转到原文地址,需要梯子):

The behavior of threads, particularly when not correctly synchronized, can be confusing and counterintuitive. This chapter describes the semantics of multithreaded programs; it includes rules for which values may be seen by a read of shared memory that is updated by multiple threads. As the specification is similar to the memory models for different hardware architectures, these semantics are known as the Java programming language memory model. When no confusion can arise, we will simply refer to these rules as "the memory model".

中文翻译:

多线程(原文用了s,thread复数形式)的行为可能会让人感到困惑和违反直觉,尤其是在没有正确同步的时候。这章描述了多线程程序的语义;它包括了一些规则,规定了被多线程更新的共享内存可以读取到哪些值。因为这个定义与不同硬件平台体系的内存模型很相似,所以这些语义一般被称为java程序语言内存模型。没有歧义的话,我们可以简单的称呼这些规则为“内存模型”。

       维基百科和oracle官网都对java内存模型进行了相同定义:内存模型描述了java多线程与共享内存的交互过程。更进一步说,java内存模型描述了共享内存中的值被多线程修改和读取的过程,规定了共享变量的可见性和执行顺序,所以将java内存模型当成堆栈和垃圾回收是错误的,堆栈和垃圾回收其实是java虚拟机内存管理(java virtual machine memory management)的内容,这块内容在本文不作介绍,有兴趣可以自己看下。

二、疑问

在进一步了解java内存模型前,先看下面3个问题:

1)java内存模型到底是什么?

2)happen-before与java内存模型什么关系?

3)volatile等关键字底层怎么实现的?

       要解答上面三个问题,就要跳出java内存模型的限制,先看下内存模型是什么,内存模型并不是java所特有的概念,由于通用计算机特殊的结构(遵循冯诺依曼体系),只有一个共享内存,内存读写速度往往是整个计算机的瓶颈,为了提高性能,增加了多CPU、缓存等部件,但也会造成多cpu在访问共享内存的情况更加复杂了,为了规范内存访问,计算机最先引入内存模型的概念。

三、计算机的内存模型

      在了解计算机内存模型之前,需要知道两个概念:内存顺序和程序顺序。

3.1. 内存顺序和程序顺序

       现在的计算机一般都是多cpu的,为了充分利用多cpu的性能,程序也会使用多线程,导致对共享变量的读写会很复杂。而在计算机发展早期,计算机结构很简单,只有一个cpu,程序也都是单线程的,cpu在执行完一个线程后才继续执行另一个线程,如下图:

单CPU单线程结构

       上图的计算机结构只有一个cpu,多线程按照队列方式顺序执行,一个线程执行完成将结果同步到内存中,下一个线程会读取到最新的内存,所以不存在并发访问内存的情况,程序运行的结果是正确的、可预测的。虽然多个线程按照队列方式顺序访问内存,但在每个线程内部,访问内存可能是乱序的,如下代码:

// 第一种情况:两个不依赖的变量

int number = 1;

boolean flag = true; 


// 第二种情况:两个依赖的变量

int number = 1;

int plus = number + 1;

       上面代码分两个情况,第一种情况:变量 number和flag是不相互依赖的,当程序执行完成时,只要满足number的值为1,并且flag的值为true,就被认为正确执行了。定义两个名词:内存顺序(memory order)和程序顺序(program order)。从内存的角度来看,当程序执行完成,内存中的number为1,flag为true,结果始终保持一致,所以认为这段程序的内存顺序是一致的;而从程序执行的角度来看,number和flag在cpu的执行顺序可能会重排,比如flag可能会先执行,number会后执行,所以认为程序顺序不总是一致的。

       第二种情况:上面的number和plus存在依赖,必须先设置number为1,才能计算plus的值,执行顺序不会被重排序,所以它们的程序顺序是一致的,内存顺序更是一致的(即这段程序执行完成,number的值一定为1,plus的值一定为2,不会存在其他值)。

       在上面两种情况的程序中,程序顺序不总是一致的(不依赖的两个变量执行顺序可能会重排序,依赖的两个变量执行顺序不会重排序),但是内存顺序总是一致的,所以程序输出的结果是可预测的,如果出现了内存顺序不一致(即一段程序执行完成,每次内存中的值不一样)的情况,程序的结果变得不可预测了。

       在上面单cpu单线程的结构中,多线程按照队列方式顺序访问内存,每个线程执行完内存顺序都是一致的,不会影响到下一个线程;而在多cpu+缓存的计算机中,为了提高内存访问效率,每个cpu会先缓存对内存的写和读,某个cpu执行完一段程序,执行完的结果可能不会立即刷新到内存中,所以内存中的值不总是一致的,即内存顺序不是一致的,为了描述可能存在的不同内存顺序,引入了内存模型的概念,在不同的内存模型中,内存顺序是不一样的。

3.2. SC内存模型

       上面用单cpu单线程的例子简单的介绍了内存顺序和内存模型的关系,单cpu单线程的内存模型很简单,内存顺序总是一致的,程序顺序只要满足:相互依赖的变量不能重排序。在多cpu多线程中,多个cpu是同时访问内存的,如果还是照搬单cpu单线程,会产生不可预测的结果,如下代码:

// cpu1

int number = 1;

int flag = true;



// cpu2

if(flag){
    print(number);
}

       cpu1和cpu2分别执行上述各自代码,cpu1负责设置number和flag的值,cpu2负责判断和输出值,这段代码的意图是:cpu1先设置number的值为1,然后设置flag的值为true,cpu2判断flag的值为true时,输出number的值为1。如果按照单cpu单线程的规定:number和flag不存在依赖,可以重排序,即cpu1可以先设置flag的值为true,然后cpu1还没有来得及设置number的值时,cpu2就开始执行了,cpu2判断if(flag)成立,但输出number的值不为1,执行结果违背了这段代码的初衷,为了保证cpu2输出的结果始终一致,引入了SC内存模型。

       多cpu的内存模型有多种,最基础的是SC模型,其他模型都是从SC模型转换来的。SC全称Sequential Consistency,顺序一致性模型。SC有两个规定:1)每个cpu内的程序顺序都不能重排;2)所有cpu的执行都有一个单一全局的内存顺序(队列)。如下图:

SC模型:多CPU程序操作和内存访问

       SC的第一条规定:从程序执行的角度来看:每个cpu内的程序顺序都不能重排。单CPU的不同线程是顺序访问内存的,一个线程执行完的内存顺序是一致的,对下一个线程没有影响;但在多CPU中,多CPU中的线程可以并发访问内存,重排序某个cpu中的共享变量的程序顺序会影响到另一个cpu,就像上面例子中的number和flag,所以SC严格规定每个CPU中的程序顺序都不能重排;

       SC的第二条规定:从内存的角度来看:所有的cpu的执行都有一个单一的内存访问顺序,多CPU的程序执行是并发的,如果访问内存也是并发的,不太好控制,如果访问的是不同的内存块影响不大,但如果访问的是同一个块,并发读写会产生不可意料的结果。为了简化,所以SC规定了不论访问的是否是同一块的内容,所有的内存访问都要排序进行。

       有了SC严格的限制,程序顺序和内存顺序都是可控的,但是有个缺点就是访问内存串行化,体现不出多CPU并发执行的优势,所以实际中,这种模型并不会被使用。

3.3. TSO内存模型

       另一种内存模型叫TSO,英文全称为:Total Store Ordering,中文名称为完全存储顺序,相对于SC模型,这种模型是针对实际的CPU结构做的优化。为了加快CPU读取内存数据,在CPU和内存的中间加入了缓存,预先读取内存中的数据。在多CPU结构中,缓存分为公共缓存和私有缓存,公共缓存是所有CPU共享的缓存,私有缓存是每个CPU独有的,不论是公共缓存还是私有缓存对CPU来说都是黑盒的,CPU只管读取数据,不论读取的数据是怎么来的,同样CPU写数据,也不会关注缓存,所以写缓存要满足两个条件:1)写缓存的数据自动同步到内存中;2)所有CPU的私有缓存应该保持一致:一个CPU写缓存,其他CPU的私有缓存都要更新。拥有缓存的多CPU结构如下:

多CPU+缓存结构

       CPU操作分为两种:load(读)、store(写),加入缓存的目的是提前缓存内存的数据,提高load的效率,但是store的速度降低了,因为CPU将数据store到内存多了写缓存的步骤,并且需要同步所有CPU的私有缓存。在上面SC模型中,不论load还是store内存中的数据,都要排队执行,如果在CPU+缓存结构中,还是按照SC模型,store操作会严重阻塞后续的load操作,这样加缓存的意义完全就没有了,不仅没能提高load的效率,反而阻塞了load。为了解决load被阻塞的问题,在CPU中加入了新的组件store buffer(写队列),如下图:

带有store buffer的多cpu+缓存结构

       每个CPU都有一个store buffer,当CPU需要执行store操作时,会将store操作先放入store buffer中,不会立即执行store操作,等待合适的时机再执行(store buffer满了等等情况会真正执行store操作),在store后面的load操作不用再等store真正执行完毕才能执行,只要store放入了store buffer中,load就可以执行了。store buffer造成的结果就是事实上store-load操作被重排序了:store操作后面的load先执行(store-load表示程序代码里先store后load,store-store,load-store,load-load依旧不能重排序)。

       TSO在放松store-load重排序的同时,也较大的放松了对内存访问顺序,TSO只规定了所有CPU的store操作保持单一全局顺序(所有CPU的store访问内存时在一个队列中排队访问内存,不能并发访问内存),而load操作可以并发访问。 相对于上面SC内存访问顺序,TSO模型中多CPU对内存的load操作效率大大提高了。

       综上,TSO有两个规定:1)程序顺序:每个CPU的store-load操作可以重排;2)内存访问顺序:所有CPU的store操作都有一个单一的全局内存访问顺序。TSO是相对宽松的内存模型,相对于SC,限制更少了,程序执行速度更快,但在多线程编程时,TSO会导致程序的结果变得不可预测了,如下例:

// 初始 a=0, b=0


// cpu1
a = 1;  // store操作
x = b;  // load操作


// cpu2 
b = 1; // store操作
y = a; // load操作

       CPU1和CPU2分别执行各自的代码,观察 x 和 y 的值。在TSO模型中,store-load操作有可能重排序,CPU1和CPU2的第一行代码都是store,第二行代码都是load,所以CPU1和CPU2内存访问顺序和输出结果可能为:

TSO模型程序执行

      上图只列出了TSO模型程序执行部分可能出现的情况,得出x和y值有四种情况,无法准确预测x和y的最终值。

3.4. 其他内存模型

PSO:在TSO基础上,解除了所有CPU的store单一全局的内存访问顺序,并允许单个CPU内的store-store重排序。

RMO:完全宽松的内存模型,对内存访问顺序不限制,并且每个cpu内的store和load都可以任意重排序。

常见计算机平台的内存模型和CPU重排序情况:

平台内存模型Load-LoadLoad-StoreStore-StoreStore-Load数据依赖
x86TSONNNYN
PowerPCRMOYYYYN
ARMRMOYYYYN

       上表中不同内存模型的CPU中store、load的重排序限制不同,但在数据依赖的情况下,都是不允许重排序的,保证了单线程始终能够正确执行,单线程的执行遵循as-if-serial,给人的感觉是代码一行一行按顺序执行的,但实际上不相互依赖的变量是可以重排序的,不会影响最终结果。

3.5. JAVA内存模型

       java程序可以部署在任何平台上,比如上面的x86和PowerPC等平台,由于x86和PowerPC等平台内存模型不一样,为了屏蔽平台差异性,JMM为java程序提供了统一的内存模型,但在统一内存模型时,JMM会面临两种问题:

1)如何保证java代码的执行结果可预测,降低编写多线程代码的难度

2)JMM内存模型不能太严格,否则会牺牲性能

       针对这两个问题,JMM的解决方法是提供“足够够用”的内存模型:1)对线程内的共享变量(类变量、类成员变量、数组)的一致性要求很严格;2)对线程的非共享变量不做任何处理。

        JMM第一条内容:对线程内的共享变量(类变量、类成员变量、数组)的一致性要求很严格。java提供了volatile、synchronized等关键字,严格规定多线程的共享变量可见性和限制重排序。

        JMM第二条内容:对线程的非共享变量不做任何处理。一个线程的非共享变量对其他线程没有影响,所以非共享变量的实际执行情况依赖部署平台的内存模型,但是都遵循as-if-serial。

        为了准确描述JMM,JMM“约法三章”,一般称为Happen-Before规则。Happen-Before描述了变量可见性和重排序,如果操作A Happen-Before 操作B, 那么操作A先执行,B后执行(程序顺序),并且A的结果对B是可见的(内存顺序)。只要遵守JMM的“约法三章”(Happen-Before),很容易编写多线程程序。Happen-Before规则如下(点击跳转到ORACLE官网JSL文档):

1)监视器的解锁Happen-Before对该监视器的后续加锁 

2)对volatile变量的写Happen-Before对该变量的后续读

3)对线程start()方法的调用Happen-Before该线程内的任何操作

4)一个线程内的所有操作Happen-Before其他线程成功join()该线程

5)任意对象的默认初始化Happen-Before程序的其他操作

       上面5条Happen-Before规则涵盖了多线程编程中的锁、共享变量读写、线程生命周期和对象初始化等等重要内容,普通开发人员不用深入了解JMM,只需要知道这5条规则,可以很轻松的处理多线程场景。

3.6. volatile实现原理

       上面的Happen-Before规则主要作用是指导开发人员编写多线程程序,对JMM实现原理并没有说明,这里用常见的volatile关键字来介绍JMM的实现原理。

       java程序可以部署在不同系统平台上,比如windows系统、linux系统等,这些系统都是基于x86或其他架构的,以x86举例,上面我们介绍过x86的内存模型是TSO,java程序运行时,java多线程最底层是被分配到CPU上执行的,所以部署在x86的java程序,底层的操作也是遵循TSO模型的,而JMM是统一的内存模型,与平台无关的,所以要将x86的TSO转换成JMM,要在底层特殊处理。

       不同平台内存模型的差异性在于cpu的读写是否能够重排,如果能够限制读、写重排序,严格规定读写顺序,就可以统一所有平台的内存模型。根据读(load)和写(store)顺序不同,重排序的限制分为4类(专业名词称为内存屏障),如下四种内存屏障:

屏障类型指令实例说明
LoadLoad BarriersLoad1 Barrier Load2在Load1和Load2中间加入屏障,确保Load1从内存中加载数据先于Load2及Load2之后的所有Load操作
StoreStore BarriersStore1 Barrier Store2在Store1和Store2中间加入屏障,确保Store1将数据立即刷新到内存中,先于store2操作及store2之后的所有Store操作
LoadStore BarriersLoad1 Barrier Store2在Load1和Store2中间加入屏障,确保Load1从内存中加载数据先于Store2及Store2之后的所有Store操作
StoreLoad BarriersStore1 Barrier Load2在Store1和Load2中间加入屏障,确保Store1将数据立即刷新到内存中,先于Load2操作及Load2之后的所有Load操作

       注:上面四种屏障在不同的平台稍有不同,比如在x86中只有3中屏障:sfence,lfence,mfence,sfence实现了StoreStore Barriers,lfence实现了LoadLoad Barriers,mfence同时满足上面4种屏障。

JMM使用上面四种屏障提供了java程序运行时统一的内存模型,以volatile为例:

1)volatile变量执行写操作,会在写之前插入StoreStore Barriers,在写之后插入StoreLoad Barriers。

       解释:volatile变量在执行写操作之前插入StoreStore Barriers,代表在执行volatile变量写之前的所有Store操作都已执行,数据同步到了内存中(将store buffer中的store操作刷新到内存);写之后插入StoreLoad Barriers,代表该volatile变量的写操作也会立即刷新到内存中,其他线程会看到最新值。

2)volatile变量执行读操作,会在读之前插入LoadLoad Barriers,在读之后插入LoadStore Barriers。

       解释:volatile变量在执行读操作之前插入LoadLoad Barriers,代表在执行volatile变量读之前的所有Load从内存中获取最新值;在读之后插入LoadStore Barriers,代表该读取volatile变量获得是内存中最新的值。

看下面这道思考题,用volatile变量修饰其中一个变量,满足当cpu2判断flag为true成立时,number的值一定为1:

初始 number=0, flag=false

// cpu1

int number = 1;

int flag = true;



// cpu2

if(flag){
    print(number);
}

       答案是:用volatile修饰变量flag。因为cpu1会在执行flag = true之前插入StoreStore Barriers,所以number = 1一定会先执行,并将number的数据刷新到内存中,然后再执行flag = true;cpu2判断flag为true成立时,number的值一定为1。

       假设不用volatile修饰变量flag,cpu1可能会重排序,flag = true会先执行;然后cpu2判断flag为true,直接输出number的值,这时还未执行number = 1,输出number的值为0。

参考资料列表:

The JSR-133 Cookbook

VM Spec Threads and Locks

Oracle Blogs

内存一致性模型

 👉👉👉 自己搭建的租房网站:全网租房助手,m.kuairent.com,每天新增 500+房源

一文读懂Memory consistency model (内存模型) 本文介绍了计算机系统中各种常见的memory model(内存模型)以及优缺点。 阅读详情

相关推荐

JVM内存模型

Java内存模型 Java内存模型是共享内存的并发模型,线程之间主要通过读-写共享变量(堆内存中的实例域,静态域和数组元素)来完成隐式通信。 Java 内存模型JMM)控制 Java 线程之间的通信,决定一个线程对共享变量的写入何时对另一个线程可见。 计算机高速缓存和缓存一致性 计算机在高速的 CPU 和相对低速的存储设备之间使用高速缓存,作为内存和处理器之间的缓...

十年代码写十年 1158

内存一致性(Memory Consistency)模型简介

内存一致性模型

JiMoKuangXiangQu的专栏 3480

Java JVM 内存模型详解

JVM内存模型Java程序运行时的核心架构,分为程序计数器、虚拟机栈、本地方法栈、堆、方法区和直接内存等区域。堆是主要存储对象实例的区域,分为新生代和老年代;方法区存储类信息和常量。JVM采用分代收集算法进行垃圾回收,包括标记-清除、复制和标记-整理等方法。合理的内存配置和垃圾收集器选择(如G1、CMS)对性能优化至关要。常见内存泄漏场景包括未关闭的连接和静态集合的滥用。建议通过监控GC日志、使用分析工具和合理设置-Xmx等参数进行调优。深入理解JVM内存模型Java性能优化的基础。

ljw714的专栏 1545

深入理解JVMJava内存模型

要了解Java内存模型,首先我们要了解什么是Java内存模型,它有什么作用?描述Java内存模型(简称JMM)的规范提案JSR-133标题《JavaMemoryModelandThreadSpecification》,通过这个标题,可以看出JMM是和线程相关的规范。此规范地指定的上对规范的说明如下通过以上描述,说明JMM规范主要是解决在多线程场景下线程间如何通信。...

weixin_43460822的博客 298

Java多线程 -- 深入理解JMMJava内存模型--(七)总结

虽然使用同步最常见的原因是保证对代码关键部分的原子访问,但实际上同步提供三个独立的功能――原子性、可见性和顺序性。

NowOrNever 4724

jvm内存模型java内存模型

java虚拟机,就碰到一系列不懂的问题。我们以前常说java把局部变量放在栈里,new出来的变量放在堆里,然后堆里的数据不定时就给回收了。然后,如果是多线程的话,每个线程自己都有会一个私有的虚拟机栈,运行每个方法时都会创建一个栈帧,栈帧里存储着局部变量啦等信息,方法结束栈帧就出栈。这好像就是我们对java内存模型的第一次理解吧。直至今天,我看了java线程通讯之java内存模型,出现了主内存、...

番茄炒土豆的博客 9382

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

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

纵有疾风起 人生不言弃 2098

JVM内存模型java内存模型

1. JVM内存模型 Java 虚拟机在执⾏ Java 程序的过程中会把它管理的内存划分成若⼲个不同的数据区域。JDK1.8 和之前的版本略有不同,下⾯会介绍到。 首先对于一个进程来说,它包含多个线程,每个线程都有其独立的内存区域,包括:虚拟机栈,本地方法栈和程序计数器。 程序计数器:线程私有 记录当前线程所执行到的字节码的行号。 每个线程都有一个独立的程序计数器,各线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存区域。 它是唯一没有OutOfMemoryError情况的内存区域。

m0_45861545的博客 6274

JVM 内存模型

目录 1.JVM 内存模型是什么? ​1.1 什么是内存模型? 2. JVM 概述 3.JVM 体系结构 4.内存管理 5.碎片回收 6. 图解JVM 6.1 说明:😁😁😁😁😁 7. 将JVM抽象表示: 7.1 说明: 1.JVM 内存模型是什么? JVM是【Java Virtual Machine(Java虚拟机)】的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Java语言虚拟机后,...

分享it知识! 5218

JVM 」不容忽视的细节:JVM内存模型Java内存模型

Java 中,JVM 内存模型JVM Memory Model)和Java 内存模型Java Memory Model, JMM)都是关于内存的关键概念,但它们处于不同层级,解决的问题也不同。JVM 内存模型关注的是运行时的内存结构,将内存划分为方法区、堆、程序计数器、虚拟机栈和本地方法栈。这些内存区域在 JVM 中具有特定的用途,比如方法区存储类信息和常量,堆则是对象实例的主要存放区。程序计数器用于跟踪当前线程的执行进度,虚拟机栈和本地方法栈则用来维护每个线程的方法调用状态和本地方法信息。

frozenpenguin的博客 2453

JVM内存模型Java内存模型

博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主。

激流丶的博客 2177

JAVA内存模型JVM内存结构

注意区分Java内存模型Java Memory Model,简称JMM)与Jvm内存结构,前者与多线程相关,后者与JVM内部存储相关。本文会对两者进行简单介绍。

weixin_43681666的博客 3951

JVM内存模型Java线程内存模型的区别

总的来说,JVM内存模型Java线程内存模型Java程序运行时的两个要方面,它们共同构建了一个稳定、高效的Java运行环境。JVM内存模型提供了整体的框架,而Java线程内存模型则在多线程情境下保证了数据的正确性和可见性。它是线程私有的,随着线程的创建而创建,随着线程的销毁而销毁。JVM内存模型主要关注Java程序在运行时的内存组织,而Java线程内存模型关注多线程环境下的数据共享和同步机制。JVM内存模型是整个Java虚拟机的内存结构,而Java线程内存模型则是在多线程环境下对内存的一种抽象。

流楚丶格念的博客 1696

JVM内存模型详解

JDK(Java Development Kit)就是java 开发工具,从图中可以看到,JDK包含JRE,Java基础类库和Java工具,这是给开发者使用的产品。JRE(Java Runtime Environment)Java运行时环境,在运行java程序代码时,提供Java运行的所有环境集合,包括核心类库,JVM实现等,在安装jdk时,安装目录下会有一个jre的目录,jre目录下有一个lib目录和一个bin目录,lib目录中存放的是Java运行是所需要的核心类库,bin中的就是JVM的实现。

wswpomos的博客 4234

CPU内存模型Java内存模型JVM内存模型

CPU内存模型Java内存模型JVM内存模型

qq_40577332的博客 1572

Java JVM内存模型详解

Java虚拟机(JVM)内存模型Java程序运行时的核心架构,它定义了程序运行时数据的存储和管理方式。理解JVM内存模型对于编写高性能、稳定的Java应用至关要。

qq_38566870的博客 1116

Java内存模型Jvm内存模型

经典问题 Q:说一下 JavaJvm)的内存模型 A:Java内存模型Jvm内存模型的抽象(深入理解JAVA虚拟机) JVM内存模型 线程安全--虚拟机栈、本地方法栈、程序计数器 非线程安全--方法区、堆(新生代,老年代)、 Meta Space(Jdk 1.8新增) Java内存模型 工作内存、主内存(对应JVM内存中的一部分) 追根溯源 Jvm内存模型 Java虚拟机运行时数据区 程序计数器:一块较小的内存空间,当前

chzh101011的博客 2487

java面试之JVM内存模型

即我们常说的永久代(Permanent Generation), 用于存储被 JVM 加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. HotSpot VM把GC分代收集扩展至方法区, 即使用Java堆的永久代来实现方法区, 这样 HotSpot 的垃圾收集器就可以像管理 Java 堆一样管理这部分内存,每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 Java 为什么能够跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会。

qq_36378416的博客 1682
上一篇: volatile官方文档解释
下一篇: What is thread in java and how its methods behave
祥先生
博客等级 码龄14年 48粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值