Java内存模型、JVM内存结构和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等关键字。
在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对象在虚拟机中的表现形式有关。
来源:
http://www.hollischuang.com/archives/2509
Java内存模型、JVM内存结构和Java对象模型的更多相关文章
- java内存模型和内存结构
java内存模型说的是多线程,网上可能会有写误导,并不是什么堆.栈.方法区,很多人都会搞混.说白了就是多线程中主线程和本地线程之间的一个数据可见性问题. jmm:java内存模型:jvm:java内存 ...
- java中栈内存与堆内存(JVM内存模型)
java中栈内存与堆内存(JVM内存模型) Java中堆内存和栈内存详解1 和 Java中堆内存和栈内存详解2 都粗略讲解了栈内存和堆内存的区别,以及代码中哪些变量存储在堆中.哪些存储在栈中.内存中的 ...
- java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)
概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...
- Java内存模型解惑--观深入理解Java内存模型系列文章有感(二)
1.volatile关键字修饰的域的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别.理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用 ...
- java并发学习--第十章 java内存模型的内存语义
一.锁的内存语义 所为的java内存模型的内存语义指的就是在JVM中的实现原则. 锁的内存语义:锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息. 我们把上面这句话再整理下: ...
- 深入理解Java虚拟机之JVM内存布局篇
内存布局**** JVM内存布局规定了Java在运行过程中内存申请.分配.管理的策略,保证了JVM的稳定高效运行.不同的JVM对于内存的划分方式和管理机制存在部分差异.结合JVM虚拟机规范,一起来 ...
- java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
- JVM并发机制的探讨——内存模型、内存可见性和指令重排序
并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...
- JVM内存模型及内存分配过程
一.JVM内存模型 JVM主要管理两种类型内存:堆(Heap)和非堆(Permanent区域). 1.Heap是运行时数据区域,所有类实例和数组的内存均从此处分配.Heap区分两大块,一块是 Youn ...
- jvm内存模型-和内存分配以及jdk、jre、jvm是什么关系(阿里,美团,京东)
参考:JVM的垃圾回收机制 总结(垃圾收集.回收算法.垃圾回收器) 1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2) ...
随机推荐
- ObjectARX开发VC版本对照表R14~AutoCAD2020
- saltstack配置文件详解
软件依赖 Python版本大于2.6或版本小于3.0: 对Python版本要求 msgpack-python: SalStack消息交换库 YAML: SaltStack配置解析定义语法 Jinja2 ...
- java8新特性(2)--接口的默认方法
1.默认方法的定义和作用 在Java8以前的版本中,由接口定义的方法是抽象的,不包括方法体.JDK8版本的发布改变了这一点,其中给接口添加了一个新的功能:默认方法.默认方法允许为接口方法定义默认实现. ...
- LeetCode 872. 叶子相似的树(Leaf-Similar Trees)
872. 叶子相似的树 872. Leaf-Similar Trees 题目描述 请考虑一颗二叉树上所有的叶子,这些叶子的值按从左到右的顺序排列形成一个叶值序列. LeetCode872. Leaf- ...
- LeetCode 503. 下一个更大元素 II(Next Greater Element II)
503. 下一个更大元素 II 503. Next Greater Element II 题目描述 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 ...
- Java设计模式--代理模式+动态代理+CGLib代理
静态代理 抽象主题角色:声明真实主题和代理主题的共同接口. 代理主题角色:代理主题内部含有对真实主题的引用,从而在任何时候操作真实主题对象:代理主题提供一个与真实主题相同的接口,以便在任何时候都可以代 ...
- kubelet tls
当成功签发证书后,目标节点的 kubelet 会将证书写入到 --cert-dir= 选项指定的目录中:此时如果不做其他设置应当生成上述除ca.pem以外的4个文件 kubelet-client.cr ...
- Shell编程学习记录
一.shell中单引号和双引号的区别: 1).单引号属于强引用,它会忽略所有被引起来的字符的特殊处理,被引用起来的字符会被原 封不动的使用,唯一需要注意的点是不允许引用自身: 2).双引号属于弱引用, ...
- 【微信小程序学习笔记】入门与了解
[微信小程序学习笔记(一)] IDE 下载安装 下载地址 官方工具:https://mp.weixin.qq.com/debug/w … tml?t=1476434678461 下载可执行文件后,可按 ...
- max_prepared_stmt_count参数
MySQL报错[mysqld-5.5.17-log]Can't create more than max_prepared_stmt_count statements (current value: ...