Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文要讨论的JVM内存结构Java内存模型Java对象模型,这就是三个截然不同的概念,但是很多人容易弄混。

首先,这三个概念是完全不同的三个概念。本文主要目的是对这三个概念加以区分以及做简单的介绍。而这每一个知识点都是又都是比较复杂的。以后会单独写文章做详细介绍。

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内存模型是根据英文Java Memory Model(JMM)翻译过来的。其实JMM并不像JVM内存结构一样是真实存在的。他只是一个抽象的概念。JSR-133: Java Memory Model and Thread Specification 中描述了,JMM是和多线程相关的,他描述了一组规则或规范,这个规范定义了一个线程对共享变量的写入时对另一个线程是可见的。

那么,简单总结下,Java的多线程之间是通过共享内存进行通信的,而由于采用共享内存进行通信,在通信过程中会存在一系列如可见性、原子性、顺序性等问题,而JMM就是围绕着多线程通信以及与其相关的一系列特性而建立的模型。JMM定义了一些语法集,这些语法集映射到Java语言中就是volatile、synchronized等关键字。

在JMM中,我们把多个线程间通信的共享内存称之为主内存,而在并发编程中多个线程都维护了一个自己的本地内存(这是个抽象概念),其中保存的数据是主内存中的数据拷贝。而JMM主要是控制本地内存和主内存之间的数据交互的。

在Java中,JMM是一个非常重要的概念,正是由于有了JMM,Java的并发编程才能避免很多问题。这里就不对Java内存模型做更加详细的介绍了,想了解更多的朋友可以参考《Java并发编程的艺术》

Java对象模型

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

HotSpot虚拟机中,设计了一个OOP-Klass Model。OOP(Ordinary Object Pointer)指的是普通对象指针,而Klass用来描述对象实例的具体类型。

每一个Java类,在被JVM加载的时候,JVM会给这个类创建一个instanceKlass,保存在方法区,用来在JVM层表示该Java类。当我们在Java代码中,使用new创建一个对象的时候,JVM会创建一个instanceOopDesc对象,这个对象中包含了对象头以及实例数据

总结

我们再来区分下JVM内存结构、 Java内存模型 以及 Java对象模型 三个概念。

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

关于这三部分内容,本文并未分别展开,因为涉及到的知识点实在太多,如果读者感兴趣,可以自行学习。后面也会发文介绍这些内容,敬请期待。

最后,这三个概念非常重要,一定要严格区分开,千万不要在面试中出现答非所为的情况

JVM内存结构、Java内存模型和Java对象模型的更多相关文章

  1. JVM内存区域的划分(内存结构或者内存模型)

    JVM内存区域的划分(内存结构或者内存模型)   运行时数据区域: 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 程序计数器(线程私有): 是当前线程所 ...

  2. JVM 垃圾回收机制和常见算法和 JVM 的内存结构和内存分配(面试题)

    一.JVM 垃圾回收机制和常见算法 Sun 公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同.GC(Garbage Collector)在回收对象前首先必 ...

  3. 系统间通信(5)——IO通信模型和JAVA实践 下篇

    7.异步IO 上面两篇文章中,我们分别讲解了阻塞式同步IO.非阻塞式同步IO.多路复用IO 这三种IO模型,以及JAVA对于这三种IO模型的支持.重点说明了IO模型是由操作系统提供支持,且这三种IO模 ...

  4. 系统间通信(4)——IO通信模型和JAVA实践 中篇

    4.多路复用IO模型 在"上篇"文章中,我们已经提到了使用多线程解决高并发场景的问题所在,这篇文章我们开始 4-1.现实场景 我们试想一下这样的现实场景: 一个餐厅同时有100位客 ...

  5. 系统间通信(3)——IO通信模型和JAVA实践 上篇

    来源:http://blog.csdn.net/yinwenjie 1.全文提要 系统间通信本来是一个很大的概念,我们首先重通信模型开始讲解.在理解了四种通信模型的工作特点和区别后,对于我们后文介绍搭 ...

  6. 面试突击(八)——JVM的结构及内存模型,是怎么划分的?

    声明:本文图片均来自网络,我只是进行了选择,利用一图胜千言的力量来帮助自己快速的回忆相关的知识点 0:再上一张Java代码的转换流程图 .java——Java程序员编写,给人看的 .class——Ja ...

  7. struct class 内存结构初探-内存模型顺序和变量的实际添加顺序一致

    typedef struct structTest { char xchar; int xint; int yint; }xStruct; @interface ViewController () { ...

  8. 【JVM】JVM内存结构 VS Java内存模型 VS Java对象模型

    原文:JVM内存结构 VS Java内存模型 VS Java对象模型 Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点.而且很多概念的名称看起来又那么相似,很多人会傻傻分不清 ...

  9. 区分 JVM 内存结构、 Java 内存模型 以及 Java 对象模型 三个概念

    本文由 简悦 SimpRead 转码, 原文地址 https://www.toutiao.com/i6732361325244056072/ 作者:Hollis 来源:公众号Hollis Java 作 ...

随机推荐

  1. Acwing-197-阶乘分解(质数)

    链接: https://www.acwing.com/problem/content/199/ 题意: 给定整数 N ,试把阶乘 N! 分解质因数,按照算术基本定理的形式输出分解结果中的 pi 和 c ...

  2. Java方法调用机制

    最近在编程时,修改方法传入对象的对象引用,并没有将修改反映到调用方法中.奇怪为什么结果没有变化,原因是遗忘了Java对象引用和内存分配机制.本文介绍3个点: ① 该问题举例说明 ② 简要阐述Java内 ...

  3. 如何将vs2015中的英文注释改为中文

    找一个中文版的vs 将 C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework        文件夹 ...

  4. luoguP3373 【模板】线段树 2

    P3373 [模板]线段树 2 969通过 3.9K提交 题目提供者 HansBug 标签 云端↑ 难度 提高+/省选- 时空限制 1s / 128MB 题目描述 如题,已知一个数列,你需要进行下面两 ...

  5. CentOS8编译openocd-0.10.0

    1.sudo yum install libusbx-devel 2. ./configure --prefix=$HOME/openocd-0.10.0 --enable-jlink CFLAGS= ...

  6. Java web分级测试评分C级感受

    上周一进行了java分级测试,但是完成的不太好,先看题目: 石家庄铁道大学选课管理系统 1.项目需求: 本项目所开发的学生选课系统完成学校对学生的选课信息的统计与管理,减少数据漏掉的情况,同时也节约人 ...

  7. sql 语句中 order by 的用法

    order by 是用在where条件之后,用来对查询结果进行排序 order by 字段名 asc/desc asc 表示升序(默认为asc,可以省略) desc表示降序 order by 无法用于 ...

  8. D. Eternal Victory(dfs + 思维)

    D. Eternal Victory time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. linux 上修改了nginx.conf 怎么重新加载配置文件生效

    步骤如下先利用/usr/local/nginx/sbin/nginx -t测试配置文件修改是否正常/usr/local/nginx/sbin/nginx -s reload重新加载 nginx 更改配 ...

  10. Java实现字串统计

    对字符串的操作,无论再难的算法题,只要时间充足,相信每个同学都可以搞定. 但是浪费太多时间去搞一个逻辑算法没太大意义,学会学习,不但可以增长自己的知识,更可以节省时间,俗话说,一寸光阴一寸金,寸金难买 ...