jvm内存模型、jvm内存结构、Java内存结构、Java内存模型(JMM)、Java对象模型的区别(吐血研究整理)

jvm内存模型、jvm内存结构、Java内存结构、Java内存模型(JMM)、Java对象模型的区别(吐血研究整理)jvm内存模型:JVM内存模型则是指JVM的内存分区。jvm内存结构:等同于Java内存结构,汉语虽然博大精深,但是也经常会因为命名很雷同让人懵逼或者混淆不清。Java内存结构:Java内存模型(JMM):java内存模型又称为JMM。为了解决Java多线程对共享数据的读写一致性问题,通过Happens-Before语义(延伸出了as-if-serial)定义了Java程序对数据的访问规则,修正之前由于读写冲突导致的Cache数据不一致的问题。具体到HotspotVM的实现..

大家好,又见面了,我是你们的朋友全栈君。

jvm内存模型:

 JVM内存模型则是指JVM的内存分区。jvm内存模型 == jvm内存结构 ==  Java内存结构!!!汉语虽然博大精深,但是也经常会因为命名很雷同让人懵逼或者混淆不清。

jvm内存结构:

Java内存结构:

可以简单的理解成是虚拟机内存中分成了哪几部分,分别是干嘛的,然后再扩展讲讲关联的知识。

Java程序执行过程中,内存会被划分为不同的数据区域,各个区域有各自的用途。

  1. 有些区域随虚拟机的启动而存在
  2. 有些区域随线程的启动而启动,随线程的结束而销毁

jvm内存模型、jvm内存结构、Java内存结构、Java内存模型(JMM)、Java对象模型的区别(吐血研究整理)

需要注意的点

  1. Java虚拟机规范,不同的虚拟机实现可能不同,但是一般都会遵守规范。
  2. 规范中方法区只是一种概念上的区域,说明了其应该具有的功能,但并没有说明其具体应该位于何处。不同的虚拟机实现,会有一定的自由度。有些虚拟机是在堆内实现的。
  3. 运行时常量池用于存放编译期的各种字面值和符号引用。不过Java并没有要求常量只能在编译期才能产生,通过String.intern也能产生。
  4. 除了图中所列的内存区域,还有一块内存可供使用,那就是直接内存。JVM规范并没有定义这一块区域,所以并不由JVM管理,是利用本地方法库直接在堆外申请的内存。例如NIO 类引入了一种基于通道(Channel)和缓冲区(Buffer)的I/O 形式,他可以使用Native 函数直接分配堆外内存,然后通过一个存储在Java 堆中的DirectByteBuffer 对象作为这块内存的引用进行操作。这样能显著提高性能,因为避免了在Java 堆和Native 堆中来回复制数据
  5. 堆和栈的数据划分并不是绝对的,JIT会针对对象分配做一定的优化(可以去学习下 逃逸分析技术,栈上分配, 标量替换优化技术)

 

 

Java内存模型(JMM):

java内存模型又称为JMM。为了解决Java多线程对共享数据读写一致性问题,通过Happens-Before语义(延伸出了as-if-serial)定义了Java程序对数据的访问规则,修正之前由于读写冲突导致的Cache数据不一致的问题。具体到Hotspot VM的实现,主要是由OrderAccess类定义的一系列的读写屏障来实现JMM的语义。

JMM并不像JVM内存结构(即java内存结构)一样是真实存在的,只是一个抽象的概念。JMM是和多线程相关的,描述了一组规则或规范,这个规范定义了一个线程对共享变量的写入时对另一个线程是可见的。简单总结下,Java的多线程之间是通过共享内存进行通信的,而由于采用共享内存进行通信,在通信过程中会存在一系列如可见性、原子性、顺序性等问题,而JMM就是围绕着多线程通信以及与其相关的一系列特性而建立的模型。JMM定义了一些语法集,这些语法集映射到Java语言中就是volatile、synchronized等关键字。所以,我理解的就是JMM就是为了解决Java多线程对共享数据的读写一致性问题而产生的一种模型!

jvm内存模型、jvm内存结构、Java内存结构、Java内存模型(JMM)、Java对象模型的区别(吐血研究整理)

总之,JVM内存模型是真的内存结构管理,Java内存模型只是为了适应和解决多线程通信而产生的一种模型,通过一些关键字修饰就可以实现并发。那其实涉及到具体的应用当中,java内存模型还有很多内容,比如重排序,volatile关键字和锁等,这其实也牵涉到多线程了,因为本身java内存模型就是多线程相关的,所以在学习java多线程这快知识的时候,很多地方都是要借助这个java内存模型进行分析和研究的!

Java对象模型:

概念理解:Java是一种面向对象的语言,而Java对象在JVM中的存储也是有一定的结构的。而这个关于Java对象自身的存储模型称之为Java对象模型。

Java对象保存在堆内存中。在内存中,一个Java对象包含三部分:对象头、实例数据和对齐填充。其中对象头是一个很关键的部分,因为对象头中包含锁状态标志、线程持有的锁等标志,即有和锁相关的运行时数据,这些运行时数据是synchronized以及其他类型的锁实现的重要基础,而关于锁标记(各种锁优化技术依赖它)、GC分代(垃圾回收依赖它)等信息均保存在_mark中。

关于一个Java对象,他的存储是怎样的,一般很多人会回答:对象存储在堆上。稍微好一点的人会回答:对象存储在堆上,对象的引用存储在栈上。今天,再给你一个更加显得牛逼的回答:

对象的实例(instantOopDesc)保存在堆上,对象的元数据(instantKlass)保存在方法区,对象的引用保存在栈上。

如果补充一下这句话就更完美了:

随着 JIT编译器的发展与逃逸分析技术(通过分析若一个对象没有逃逸出一个方法,那么该对象在栈上分配空间,该对象随着栈的销毁而销毁)的逐渐成熟, 栈上分配, 标量替换优化技术(将部分字段使用标量存储)将会导致一些微妙的变化发生, 所有的对象都分配在堆上也逐渐变得不是那么”绝对”了。

其实如果细追究的话,上面这句话【对象的实例(instantOopDesc)保存在堆上,对象的元数据(instantKlass)保存在方法区,对象的引用保存在栈上】有点故意卖弄的意思。因为我们都知道。方法区用于存储虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 所谓加载的类信息,其实不就是给每一个被加载的类都创建了一个 instantKlass对象么。

废话不多说,上代码直观的感受下:

class Model {
    public static int a = 1;
    public int b;
 
    public Model(int b) {
        this.b = b;
    }
}
 
public static void main(String[] args) {
    int c = 10;
    Model modelA = new Model(2);
    Model modelB = new Model(3);
}

jvm内存模型、jvm内存结构、Java内存结构、Java内存模型(JMM)、Java对象模型的区别(吐血研究整理)

每一个Java类,在被JVM加载的时候,JVM会给这个类创建一个instanceKlass,保存在方法区,用来在JVM层表示该Java类。当我们在Java代码中,使用new创建一个对象的时候,JVM会创建一个instanceOopDesc对象,这个对象中包含了两部分信息,对象头以及元数据。对象头中有一些运行时数据,其中就包括和多线程相关的锁的信息。元数据其实维护的是指针,指向的是对象所属的类的元数据

总结:

jvm内存模型 == jvm内存结构 ==  Java内存结构,和Java虚拟机的运行时内存分区有关。
Java内存模型,和Java的并发编程有关。
Java对象模型,和Java对象在虚拟机中的表现形式有关。

 

参考资料:https://blog.csdn.net/weixin_42762133/article/details/95735737

https://blog.csdn.net/qiang_zi_/article/details/100147613

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/142692.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • linux下vi操作Found a swap file by the name

    linux下vi操作Found a swap file by the name

    2021年10月22日
  • 目标检测综述_通用目标检测

    目标检测综述_通用目标检测前言图片分类任务我们已经熟悉了,就是算法对其中的对象进行分类。而今天我们要了解构建神经网络的另一个问题,即目标检测问题。这意味着,我们不仅要用算法判断图片中是不是一辆汽车,还要在图片中标记出它的位置,用边框或红色方框把汽车圈起来,这就是目标检测问题。其中“定位”的意思是判断汽车在图片中的具体位置。近几年来,目标检测算法取得了很大的突破。比较流行的算法可以分为两类,一类是基于Regio…

    2022年10月13日
  • windows下搭建tracker服务器

    windows下搭建tracker服务器RT,需要下载工具下载,解压,得到一个BitCometTracker_0.5[做服务器tracker]的文件夹,打开“BitCometTracker_0.5”文件夹,双击运行“BitCometTracker”打开软件之后,状态是停止的的状态,需要点击“run”这样就行了,如果需要修改配置端口,需要点击“config”架设好后,您的tracker服务器…

  • Linux内核编程_linux内核开发工具

    Linux内核编程_linux内核开发工具【转载】Linux内核编程与应用编程对比

  • 基于jenkins的CICD使用

    基于jenkins的CICD使用前言:这篇文章主要讲一讲基于jenkins的CICD使用基于jenkins的CICD使用一、简介二、CICD流程图三、CICD效果四、jenkins编译方式五、新创建job六、pipeline脚本说明七、疑问解答与加群交流学习一、简介为了提升线下测试效率,缩短测试时间,提升提测代码质量,规范流程,缩短测试准备和执行时间,缩短问题定位时间,提供预测性指标,规范CICD流程,以提升整体团队效率。二、CICD流程图三、CICD效果大致可查看到的job如下:点击其中可查看具体编译情况:四、

  • debian详细安装教程_debian 安装ssh

    debian详细安装教程_debian 安装ssh1.安装 按照这篇图文并茂的文章安装http://www.itwhy.org/2011/07-27/694.html2.安装ssh安装好后登录并切换到root用户,使用命令apt-getinstallssh一串协议后输入大写Y同意协议,ssh会自动安装并启动

    2022年10月19日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号