Java是一门面向对象、跨平台的语言,其对象和内存一直是比较难的知识点。此外,许多概念的名称看起来非常相似,以至于很多人无法区分它们。比如本文要讨论的JVM内存结构、Java内存模型和Java对象模型,是三个完全不同的概念,但是很多人容易混淆。可以说很多高级开发者甚至不了解JVM内存结构、Java内存模型和Java对象模型的概念以及它们之间的区别。甚至我也见过一些面试官不是很清楚。不信你去网上搜一下Java内存模型,其实介绍JVM内存结构的文章会有很多。首先,这三个概念是三个完全不同的概念。本文主要对这三个概念进行区分和简要介绍。其中每个知识点都可以单独写成一篇文章,本文不做深入介绍。感兴趣的朋友可以加入我的知识星球,和球友一起学习。JVM内存结构我们都知道。Java代码是运行在虚拟机上的,虚拟机在Java程序执行过程中会将托管内存划分为若干个不同的数据区域。这些领域有自己的目的。.其中一些区域随着虚拟机进程的启动而存在,而一些区域则根据用户线程的启动和结束而建立和销毁。在《Java虚拟机规范(Java SE 8)》中,JVM运行时内存区的结构描述如下:各个区域的作用不是本文的重点,这里不再详细介绍。这里有几点需要特别注意:1.以上是Java虚拟机规范。不同的虚拟机实现会有所不同,但大体遵循规范。2、规范中定义的方法区只是一个概念区,说明了它应该具有什么功能。但它没有具体说明这个区域应该在哪里。因此对于不同的虚拟机实现有一定的自由度。3、不同版本中方法区的位置不同。上图中的划分是逻辑区域,不是绝对意义上的物理区域。因为有些版本的JDK中的方法区实际上是在堆中实现的。4、运行时常量池,用于存放编译时产生的各种字面量和符号应用。但是,Java语言并不要求常量只能在编译时生成。例如,在运行时,String.intern也会将新常量放入池中。5.除了上面介绍的JVM运行时内存之外,还有一个内存区域可以使用,那就是直接内存。Java虚拟机规范并没有定义这块内存区域,所以它不受JVM管理。是使用本地方法库直接在堆外申请的一块内存区域。6、堆和栈的数据划分不是绝对的。例如,HotSpot的JIT会相应地优化对象分配。综上所述,总结一下,JVM内存结构是由Java虚拟机规范定义的。描述了在Java程序执行过程中由JVM管理的不同数据区域。每个区域都有其特定的功能。Java内存模型Java内存模型看起来类似于Java内存结构(JVM内存结构)。很多人误以为两者是一回事,导致面试过程中往往答错。在前面关于JVM内存结构的图中,我们可以看到Java堆和方法区是多个线程共享的数据区。也就是说,多个线程可能能够操作存储在堆或方法区中的相同数据。这就是我们常说的“Java线程通过共享内存进行通信”。Java内存模型翻译自英文JavaMemoryModel(JMM)。事实上,JMM并不像JVM内存结构那么真实。他只是一个抽象的概念。如JSR-133:Java内存模型和线程规范中所述,JMM与多线程相关。它描述了一组规则或规范。本规范定义当一个线程写入一个共享变量时,它对另一个线程是可见的。的。那么简单总结一下,Java的多线程是通过共享内存进行通信的,而由于使用共享内存进行通信,在通信过程中会存在可见性、原子性、顺序性等一系列问题,而JMM呢是围绕多线程通信以及与之相关的一系列特性构建的模型。JMM定义了一些语法集,这些语法集映射到Java语言中的volatile、synchronized等关键字。在JMM中,我们将多线程间通信的共享内存称为主内存,而在并发编程中,多个线程维护自己的本地内存(这是一个抽象的概念),其中存储的数据就是主内存中的数据拷贝.JMM主要控制本地内存和主存之间的数据交互。在Java中,JMM是一个非常重要的概念。正是因为有了JMM,Java的并发编程才能避免很多问题。Java内存模型这里就不做更详细的介绍了。想了解更多的朋友可以参考《Java并发编程的艺术》。Java对象模型Java是一种面向对象的语言,Java对象在JVM中的存储也有一定的结构。而这种关于Java对象本身的存储模型就称为Java对象模型。在HotSpot虚拟机中,设计了一个OOP-Klass模型。OOP(OrdinaryObjectPointer)是指普通对象指针,Klass用于描述对象实例的具体类型。对于每一个Java类,当它被JVM加载时,JVM会为这个类创建一个instanceKlass,保存在方法区,在JVM层用它来表示Java类。当我们在Java代码中使用new创建对象时,JVM会创建一个instanceOopDesc对象,其中包含对象头和实例数据。这是Java对象的一个??简单的OOP-Klass模型,即Java对象模型。综上所述,先区分一下JVM内存结构、Java内存模型和Java对象模型这三个概念。JVM内存结构与Java虚拟机的运行时区有关。Java内存模型与Java的并发编程有关。Java对象模型与Java对象在虚拟机中的表示有关。关于这三个部分,本文不单独展开,因为涉及到的知识点太多了。读者有兴趣可自行学习。稍后我会发文介绍这些内容,敬请期待。***,这三个概念很重要,一定要严格区分,面试时千万不要回答不当。【本文为专栏作家霍利斯原创文章,微信公众号Hollis(ID:hollishuang)撰文】点此阅读更多本作者好文
