现在的位置: 首页 > 编程语言 > 正文

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

2020年02月13日 编程语言 ⁄ 共 1460字 ⁄ 字号 评论关闭

首先,这两者是完全不同的概念,绝对不能混为一谈。

1.什么是Java内存模型?

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

多线程编程的普遍问题是:

所见非所得 无法肉眼检测程序的准确性 不同的运行平台表现不同 错误很难复现

故JVM规范规定了Java虚拟机对多线程内存操作的一些规则,主要集中体现在volatile和synchronized这两个关键字。

volatile 是JVM提供的对共享变量在多线程读写时的可见性保证,主要作用是对volatile修饰的共享变量禁止被缓存(这里跟CPU的高速缓存和缓存一致性协议有关),不做重排序(重排序:在CPU处理速度远大于内存读写速度的现状下为了提高性能而进行的优化),但是并不保证共享变量操作的原子性。 synchronized 是JVM提供的锁机制,通过锁的特性和内存屏障保证锁住区域操作的原子性、可见性、有序性。 锁争抢的是对象(static锁的是类对象,非static锁的是当前对象,即this,锁方法块锁的是自定义对象)在堆内存中对象头的一块内存的“主权”,只有一个线程能获取该“主权”,即排他性,通过锁的排他性保证对锁住区域的操作的原子性 通过在代码前后加入加载屏障(Load Barrier)和存储屏障(Store Barrier),能保证锁住代码块或者方法中对共享变量的操作的可见性 通过在代码前后加入获取屏障(Acquire Barrier)和释放屏障(Release Barrier),能保证锁住代码块或者方法中对共享变量的操作的有序性

2.什么是JVM运行时数据区?

JVM运行时数据区,是Java虚拟机在运行时对该Java进程占用的内存进行的一种逻辑上的划分,包括方法区、堆内存、虚拟机栈、本地方法栈、程序计数器。这些区块实际都是Java进程在Java虚拟机的运作下通过不同数据结构来对申请到的内存进行不同使用。

方法区:JVM用来存储加载的类信息、常量、静态变量、编译后的代码等数据。不同虚拟机有不同的实现,oracle的HotSpot在Java7中方法区放在永久代,Java8中方法区放在元空间,并通过GC机制来管理。 虚拟机栈:每个线程私有的空间,由多个栈帧组成,一个方法对应一个栈帧,栈帧包括局部变量表、操作数栈、动态链接、方法返回地址、附加信息等。栈内存默认最大1M,超出跑出StackOverFlowError。 本地方法栈:类似虚拟机栈,是为虚拟机使用native本地方法而准备的。具体实现由虚拟机厂商来实现。HotSpot虚拟机中实现与虚拟机栈一致,同时超出大小抛StackOverFlowError。 程序计数器:记录当前线程执行字节码的位置,存储的是字节码指令地址,如果native方法,则为空。CPU同一时间只能执行一条线程中的指令,线程切换后通过程序计数器来恢复正确的执行位置。 堆内存:所有线程都可以访问修改,存放的是对象实例,是数据区中占用空间最大的部分,在HotSpot虚拟机中分为新生代和老年代,新生代又分为Eden区和Survivor0区、Survivor1区。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

本文标题: Java内存模型与JVM运行时数据区的区别详解

以上就上有关Java内存模型与JVM运行时数据区的区别详解的相关介绍,要了解更多java,内存模型,jvm运行,数据区内容请登录学步园。

抱歉!评论已关闭.