简单说说jvm的对象存储与访问

作者: MaxZing | 来源:发表于2016-05-10 17:59 被阅读368次
JDK技术组成.png

图上所涉及的是Java的技术组成,确实,没有必要全部深入了解。但是大致的框架是有必要明确的。业务层的程序员可能并不了解这些,所以我还是弄一篇笔记用来学习和分享

传统意义上,Java包括了:

  • Java程序设计语言
  • 各种平台上的Java虚拟机(JVM)
  • class文件格式
  • Java API
  • 第三方Java库

jvm是Java最小运行环境,JDK是Java最小开发环境

想知道对象怎么创建的,就要先知道,JVM的内存管理,先介绍一下

内存管理

Java比C++多了一个内存管理,减少了程序员对内存回收的操作,方便的同时也带来了新的麻烦,所以我们需要了解Java的内存管理技术,避免过于浪费性能。

Java虚拟机运行时数据区
  • 程序计数器
    标记当前线程程序执行到的位置,这样可以方便线程切换时恢复到正确的执行位置。所以计数器是线程私有数据。
  • 虚拟机栈
    初学Java的时候,老师喜欢把Java内存模型分为堆内存和栈内存,栈内存就是这玩意儿,是Java方法执行的内存模型,每个方法执行的时候都会创建一个栈帧(Stack Frame) 存储局部变量,操作数栈,动态链接,方法出口等。
    所以堆内存和栈内存的分类是比较粗糙的,实际上要复杂的多。
    在虚拟机中,如果线程请求的深度大于栈的深度就会出现StackOverflowError错误,如果是动态扩展的栈,当扩展无法获得足够的内存会抛出OutOfMemoryError错误
  • 本地方法栈
    执行Native方法的服务,具体看JVM的实现,方便程序调用本地的方法与服务。
  • Java堆
    Java堆是被一群线程共享是一块内存,应该是最大的一块存储空间了。在虚拟机启动时创建,GC管理的最大的一块地方。这里可以划分出多个线程私有的缓冲区,但是这些划分与存放内容无关,这里主要存的,是对象。当然,这里是可拓展的。
  • 方法区
    存放虚拟机加载的类信息,常量,静态变量,即时编译的代码数据。
  • 运行时常量池
    是方法区的一部分,Class文件除了类版本,字段,方法,接口等描述信息外,还有一项是常量池,存放编译时,生成的各种字面量,符号引用,这部分内容将在类加载后进入方法区的运行时常量池内

上面说了这么多,那Java是怎么创建对象的呢?

对象的创建

当虚拟机获得new指令的时候,首先会在常量池中找到类符号引用,检查符号是否被加载、解析、初始化过,检查通过以后执行未执行的操作,然后虚拟机会为新对象分配内存(把一块确定大小的内存从堆中分出来)。
在规整的Java堆内存中(用过的内存放在一边,没用过的内存放在另一边,中间靠一个指针来分开),分配的内存就是将指针移动一下,让出对象对应大小的位置。而在非规整的堆内存中,空闲与非空闲的相互交错,这时候,Java会维护一个列表,记录内存可用的区块,分内存给对象的时候,就是找到一块足够大的地方,存下这个对象,并更新记录表。不同的JVM有不同的记录方式。

这样分配如何保证线程安全呢,即使在仅仅改变内存指针的行为,在并发情况下,也不是安全的,可能线程A正在给对象分配内存,还没来得及修改,而线程B却使用了老的指针地址。这样,要么对修改指针做同步处理,要么把内存分配动作按线程划分在不通空间(本地线程分配缓冲)。分配完,对内存进行清零,让后对对象进行初始化。将对象的哈希码,GC分代年龄存放在对象头中。

对象的访问定位

访问对象要靠栈上的reference数据寻址。Java没有定义这个引用如何定位,所以有两种方式访问。(句柄访问,指针访问)
句柄访问:栈reference中存储的是句柄的地址,对应的堆的句柄池内的数据。如图:

句柄访问简单示意图

指针访问:指针直接访问对象


指针访问简单示意图

句柄访问存储比较稳定,对象移动的时候只需要改变指针内的地址,reference内的数据不用改变,指针直接访问速度更快,节省开销。

虽然Java有GC,但是GC不是万能的,内存溢出还是会存在。所以应该说了解JVM,应该也是是Java程序员的必修课之一吧。

相关文章

  • 简单说说jvm的对象存储与访问

    图上所涉及的是Java的技术组成,确实,没有必要全部深入了解。但是大致的框架是有必要明确的。业务层的程序员可能并不...

  • JVM

    JVM之内存模型JVM之对象定位与访问JVM之Java垃圾回收机制JVM之类加载

  • 六、Class字节码指令解释执行

    JVM指令主要包含了一下几种类型:加载和存储指令、运算指令、类型转换指令、对象创建与访问指令、操作数栈管理指令、控...

  • javascript设计模式——数据访问对象

    数据访问对象模式: 抽象和封装对数据源的访问与存储,DAO通过对数据源链接的管理方便对数据的访问与存储 代码实现:...

  • 访问对象存储资源下载变成预览

    访问对象存储资源下载变成预览 上传文件、图片到棱束链对象存储后,使用浏览器访问棱束链对象存储资源,对象存储资源被强...

  • Java进阶 - JVM 内存管理机制探秘

    内容概述 JVM 运行时数据区概述 JVM 对象分配、布局与访问过程 GC机制与内存分配策略 主要以 HotSpo...

  • JVM之对象定位与访问

    简单说下上面代码实例化类A的内存分配情况,引用变量a保存在虚拟机栈中的本地变量表,该引用指向的对象实例数据保存在J...

  • 一篇了解JVM堆(Heap),你学会了吗?

    1.JVM堆的概念 JVM中的堆是用来存放对象的内存空间,几乎所有的Java对象、数组都存储在JVM的堆内存中。比...

  • JVM中的对象头信息

    JVM中对象头信息内容 对象头信息是与对象自身定义的数据无关的额外存储成本,HotSpot虚拟机中的对象头分为两部...

  • Synchronize的实现原理

    1 Java对象头信息 Java对象在JVM中的结构如下: java对象包括: Mark Word(存储对象的ha...

网友评论

    本文标题:简单说说jvm的对象存储与访问

    本文链接:https://www.haomeiwen.com/subject/fqyjrttx.html