> 文章列表 > 面试篇-从今天开始彻底分清Java内存模型JMM和运行时数据区

面试篇-从今天开始彻底分清Java内存模型JMM和运行时数据区

面试篇-从今天开始彻底分清Java内存模型JMM和运行时数据区

“相信很多人会把Java内存模型与Java运行时数据区给搞混淆”

Java内存模型和Java运行时数据区是两个不同的概念,很容易让人混淆。下面简单介绍一下它们的区别:

Java内存模型(JMM)是Java虚拟机规范中定义的一种内存模型,它描述了Java程序如何在多线程环境下访问共享内存。JMM主要关注的是多线程环境下共享变量的可见性、原子性和有序性等问题。

Java运行时数据区则是Java虚拟机在运行时创建的一个内存区域,用于存储Java程序运行时所需要的数据结构和对象实例。Java运行时数据区包括堆、方法区、虚拟机栈、本地方法栈和程序计数器等部分。

大家看看下面2张图就能分清了。

1、Java内存模型概念

JMM(Java Memory Model)是Java虚拟机规范中定义的一种内存模型,它描述了Java程序如何在多线程环境下访问共享内存。JMM主要是为了屏蔽各种硬件和操作系统对内存访问的差异而定义出来的内存模型。JMM定义了一个抽象的计算机内存模型,包括主内存和工作内存两部分。

Java内存模型(Java Memory Model,JMM)定义了Java程序如何在多线程环境中访问共享内存。Java内存模型主要由主内存和工作内存两部分组成。
1. 主内存
主内存是所有线程共享的内存区域,也是Java内存模型中的核心部分。主内存中保存着Java对象的实例数据、类信息、方法等。
在多线程环境下,当一个线程修改了主内存中的共享变量时,其他线程并不会立即看到这个变量的修改。这是因为每个线程都有自己的工作内存,与主内存之间存在缓存数据不一致的问题。
2. 工作内存
每个线程都有自己的工作内存(Thread Local Memory),它是线程私有的内存区域。工作内存中保存着该线程使用到的共享变量的副本拷贝。
当一个线程需要使用某个共享变量时,它会首先从主内存中读取该变量的值到自己的工作内存中,并对它进行操作。操作完成后,该线程再将变量的值写回主内存中。在这个过程中,其他线程并不能直接访问到该线程的工作内存。
3. 内存交互操作
Java内存模型还定义了一些内存交互操作,包括lock、unlock、read和write等。这些操作可以保证多线程环境下共享变量的可见性和一致性。
lock和unlock:用于对共享变量进行加锁和解锁,确保同一时刻只有一个线程可以访问该变量。
read:用于将工作内存中的值传递到主内存中。
write:用于将主内存中的值传递到工作内存中。
4. 内存屏障
Java内存模型还定义了内存屏障(Memory Barrier),用于控制内存交互操作的顺序和可见性。
内存屏障分为四种类型:

  • LoadLoad屏障:保证load指令之前的所有load指令已经执行完毕。
  • StoreStore屏障:保证store指令之前的所有store指令已经执行完毕。
  • LoadStore屏障:保证load指令之前的所有指令都已经执行完毕,并且能够读取到最新的变量值。
  • StoreLoad屏障:保证store指令之前的所有指令都已经执行完毕,并且该指令所写入的变量值对于其他线程可见。

2、相关问题

  1. 什么是JMM?

JMM(Java Memory Model)是Java虚拟机规范中定义的一种内存模型,它描述了Java程序如何在多线程环境下访问共享内存。

2. JMM的作用是什么?

JMM的主要作用是保证多线程环境下的数据可见性、原子性和有序性。通过JMM的规范,我们可以确保多线程程序的正确性和可靠性。

3. 什么是主内存和工作内存?

主内存是所有线程共享的内存区域,也是Java内存模型中的核心部分。工作内存是每个线程私有的内存区域,保存着该线程使用到的共享变量的副本拷贝。

4. 什么是内存屏障?

内存屏障(Memory Barrier)是Java内存模型中用来控制内存交互操作顺序和可见性的一种机制。内存屏障分为四种类型:LoadLoad屏障、StoreStore屏障、LoadStore屏障和StoreLoad屏障。

5. synchronized、volatile、Lock等关键字和API有什么作用?

这些关键字和API都是Java多线程编程中用来实现同步的机制,用于保证多线程环境下共享变量的可见性、原子性和有序性。其中synchronized关键字用于实现悲观锁机制,volatile关键字用于实现轻量级同步机制,Lock接口用于实现更加灵活的锁机制。

6. 什么是线程安全?

线程安全指的是在多线程环境下,程序能够正确地处理共享数据,不会出现不确定或者错误的结果。线程安全通常需要使用同步机制来保证共享变量的可见性、原子性和有序性,从而避免竞态条件和死锁等问题。

7. Java中的final关键字有什么作用?

final关键字可以用来修饰变量、方法和类。当final关键字修饰一个共享变量时,它可以确保该变量的值在初始化之后不会被修改。这也就意味着,其他线程读取该变量的值时,可以获得该变量的最新值,从而保证了线程安全性。

8. java内存模型和java运行时数据区的关系?

主内存对应着java堆和方法区;工作内存对应着java栈,线程私有。

作者:玄明Hanko
链接:https://juejin.cn/post/7220712723599081509/
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。