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)


相关推荐

  • 移位运算(无符号移位运算,有符号移位运算)

    移位运算(无符号移位运算,有符号移位运算)移位运算,所有移位以5和-5为例移位运算左移(<<)正数负数带符号右移(>>)(右移向前面补对应的符号位所对应的值(正数补0,负数补1))正数负数不带符号右移(>>>)(>>>为java独有语法)正数负数移位运算可以移位运算的类型有:iuint,int,lang等类型.我们本次使用int类型一个int类型占4个字节,共32位,带符号…

  • java创建文件 权限_JAVA创建文件后权限不足的问题,无法设置权限的问题「建议收藏」

    java创建文件 权限_JAVA创建文件后权限不足的问题,无法设置权限的问题「建议收藏」JAVA创建文件后权限不足的问题,无法设置权限的问题凯哥java凯哥java前言:在工作中,项目使用到文件上传,这个功能是很常见的吧。今天,凯哥修改自己的公众号的时候,遇到了一个问题:那就是上传后的文件访问不到,使用浏览器访问不到了。怎么办呢?经过多次查询,发现竟然是因为tomcat的配置原因!正文:最近在Linux系统中通过tomcat部署项目后,由于程序有上传文件功能。而上传后的却无法查看…

  • Pycharm我认为最好看,最舒服的主题配色和字体设置

    Pycharm我认为最好看,最舒服的主题配色和字体设置File->Settings,如下图所示设置主题Editor->ColorScheme->Python,如下图所示,在右侧第一个框中下拉选择Twilight。这个主题看着就很舒服。设置字体Editor->General->Font,在右侧的Fonts是选择字体样式为Monospaced,大小Size设为18,行间距Linespacing设为1.2这样就设置完成啦!大概是这个样子,有没有觉得看起来hen舒服。如果有觉得更好的主题样式,欢迎大家一起来分享。

  • informatik_bug report

    informatik_bug report
    使用工具:PowerCenterDesigner
    版本:DesignerVersion8.6.1HotFix100124412(R179D88)
    平台:CitrixWebInterface
    Bug:
    1、Mappings->ParametersandVariables…和Union[GroupPorts]里PortName粘贴未双击时,显示已改变,但偶尔失效。
    2、Union[GroupPorts]连线后顺

    2022年10月29日
  • SVN——SVN项目迁移到GIT

    svn有很多优点,但是git的出现对svn的冲击的确很大,现在很多公司项目的都迁移的git上了,下面是我自己在做svn迁移项目到git上面时候整理的一些资料。暂时就些整理这些,具体的操作如果有看不懂的,可以和我联系!右侧的qq号,欢迎一起探讨。 相关操作: 1:命令行执行##clone svn -> git 地址支持协议 : svn://, http://, https://. 注意这个 UR

  • 好用的vue富文本编辑器记录[通俗易懂]

    好用的vue富文本编辑器记录[通俗易懂]vue-quill-editorhttps://github.com/surmon-china/vue-quill-editorhttps://www.npmjs.com/package/vue-quill-editorhttps://blog.csdn.net/nickroprak/article/details/86645519(自定义图片上传)*默认上传图片为base64编吗…

    2022年10月14日

发表回复

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

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