你必须了解的java内存管理机制(二)

  • 时间:
  • 浏览:9
  • 来源:木木娱乐网_提供晓轩资源网技术_技术QQ网资讯

  JVM完成对象内存的分配及对象初始化并且,会返回对象的地址,或者压入操作数的栈顶,供后续操作!

  1)、 指针碰撞

  让让我们都看看对应的字节码

  JVM遇到new指令时,先检查指令参数(里面字节码中的#2)有无 能在常量池中定位到另一个 类的符号引用(里面最终定位到常量池中的com/test/entity/People):

  1)、不可能 能定位到,检查你这个 符号引用代表的类有无 已被加载、解析和初始化过;

  2)、 本地守护进程分配缓冲区:把分配的内存按照不同的守护进程划分在不同的空间进行,每个守护进程在java堆区预先分配一小块内存,称为本地守护进程分配缓冲区(Thread Local Allocation Buffer)。哪个守护进程都回会 分配就从哪个守护进程的TLAB上分配,不到在TLAB用完都回会 分配新的TLAB的并且才都回会 做同步处里(通过上或多或少中的CAS机制)。

  1)、 句柄法律法律辦法 访问对象时,多一次指针定位的时间开销。或者对象移动时(垃圾回收时常见的动作),栈上的变量的引用不都回会 修改,只需改变句柄中实例数据指针。

  让让我们都里面不可能 把对象创建的问题报告 处里了,一齐让让我们都也都知道,引用类型的变量存储的是**对象的引用**!那你这个 引用类型数据为什定位到堆中的对象呢?目前主流的对象访问法律法律辦法 一种生活生活:

  内存分配并且,就都回会 初始化实例对象了,虚拟机都回会 将分配到的内存空间中的数据类型都初始化为零值(不包括对象头,不可能 是使用TLAB,初始化0值的操作提前至分配TLAB时)。接下来虚拟机要对对象进行必要的设置,这类你这个 对象是哪个类的实例、怎么才能 才能 都回会 找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息,哪些信息都存放满对象的对象头中。做完以上并且,从虚拟机视角来看,另一个 新的对象不可能 产生了!

  2)、不可能 不到定位到,或不到检查到,就先执行相应的类加载过程;

  1)、 同步处里:JVM采用CAS(Compare and Swap)机制添加失败重试的法律法律辦法 ,保证更新操作的原子性。CAS机制是一种生活轻量级锁机制,后续在聊多守护进程的并且再讲!

  咱们到了适婚年龄,也就该找个对象了吧!你看上了另一个 姑娘,长得楚楚动人,就跑去跟他妈说:“我愿意另一个 对象,把你女儿嫁给我吧!”。她妈妈倒是十分爽快:“好啊,我女儿总得有个地方住吧,小伙子你有房吗?”。这并且场面一度十分尴尬,心里嘀咕着“这麼来越多这麼来越多 国家能分配房子就好了!”。这在当前社会显然不现实,毕竟咱们还没进入共产主义社会!然而在JVM王国里,对象住的“房子”却是“国家”统一分配的。国家集中圈了一大块“地”,谁家要娶“媳妇”,就给让让我们都家分配一块“地”,“媳妇”胖点呢,地就大或多或少,“媳妇”瘦或多或少呢,“地”就小或多或少。在这里,你另一个 人回会 一齐拥有多个对象,在这里,多当事人回会 拥有同另一个 对象。这麼来越多这麼来越多这里的老百姓安居乐业、这里一片祥和……当然,不可能 这块“地”大小有限,而你又一齐拥有这麼来越多这麼来越多对象,还有当事人也要娶对象,这麼来越多这麼来越多哪些这麼多再了的对象的“地”国家就会进行统一征收(当然这里这麼多再给补贴,毕竟是免费分配的~)以继续分给当事人用。

  里面扯了不到多,相信你不可能 知道“你”就代表着另一个 守护进程,“国家”指的是JVM,“国家”圈的一块“地”这麼来越多这麼来越多 堆空间,你娶的“对象”这麼来越多这麼来越多 实例对象,“国家”分配地的动作这麼来越多这麼来越多 内存分配,而国家征收的动作这麼来越多这麼来越多 垃圾回收。

  dup命令没猜错说说是duplicate的简写。在讨论dup命令前,让让我们都先看另一个 简单的例子

  在上文让让我们都提过或多或少问题报告 ,你的对象是为什new出来的?new出来又放满哪里?为什引用的? 老规矩,让让我们都还是通过字节码来了解一下。

  具体类的加载、解析、初始化的过程让让我们都回会 去查找JVM类加载机制相关资料,这里就不展开啦!让让我们都都回会 知道的是你这个 步保证了在法律法律辦法 区中,居于要创建实例对象的类对象

  JVM在堆区划分一块内存作为句柄池,引用类型变量中存储这麼来越多这麼来越多 对象的句柄地址。对象句柄包含另一个 地址(如下图):

  1、在堆中分配的对象实例数据的地址。

  2、你这个 对象类型数据地址。

      

  2)、 直接指针对象相对句柄法律法律辦法 访问节省了一次指针定位的时间开销,性能更好。不可能 对象访问非常频繁,提升会更明显!或者在对象移动时,栈上的变量的引用本来需要 变化。

  不可能 88你这个 值在两根说说中都回会 重复赋给另一个 变量,这麼来越多这麼来越多使用dup指令对栈顶的值进行了基因重组,且压入栈顶。让让我们都在new对象的并且,new指令里面回会 紧跟dup指令!或者是invokespecial和astore指令,相信聪明的你应该想到invokespecial和astore指令回会 都回会 从栈顶弹出值来执行!在执行完dup指令后,操作数栈栈顶全是另一个 指向该对象实例内存的reference数据,不可能 <init>法律法律辦法 有参数,还都回会 把参数加载到操作栈。

  另一个 对象都回会 占用多大的内存?你这个 问题报告 其着实类加载完成后就不可能 选择啦!JVM回会 通过普通java对象的类元信息选择对象大小。为对象分配内存相当与把一块选择大小的内存从java堆中划分出来。不到问题报告 来了,不到大的一块堆空间摆在JVM的转过身,JVM该划哪一块空间来分配内存呢?随机找一块空间分配算了?or紧挨着并且分配的空间里面进行分配?这里都回会 说到的是一种生活分配法律法律辦法 :

  不可能 要找对象的人这麼来越多了,这麼来越多这麼来越多分配的操作也很频繁,不到摆在“国家”的问题报告 就来了:为什合理分配?为什最大限度的提高空间利用率?为什提高分配速率?这麼多再了的空间为什回收?为什知道哪些空间这麼多再了?里面这麼来越多这麼来越多问题报告 都都回会 结合里面的垃圾回收相关的内容来讨论,这里只讨论分配内存的法律法律辦法 。

  invokespecial指令调用对象实例法律法律辦法 <init>,通过符号引用#3定位到的是People对象的实例法律法律辦法 <init>。这并且操作数栈栈顶值(指向对象实例的内存reference)会被弹出(不可能 <init>法律法律辦法 有参数,参数也会出栈)。执行<init>法律法律辦法 会在java虚拟机栈中创建<init>法律法律辦法 的栈帧(相关栈和栈帧的介绍看上一篇文章),或者把出栈的数据放满栈帧的局部变量表中。变量表中指向对象实例的内存reference这麼来越多这麼来越多 让让我们都总爱用到的this,表示对该对象实例进行操作!执行完该指令后,另一个 完整篇 的对象就创建完成啦!

  让让我们都能看一遍,原因你这个 种法律法律辦法 的差异主要取决于java堆有无 规整,而java堆有无 规整又是由jvm采用的垃圾埋点器有无 包含压缩功能决定的。使用Serial、ParNew等带Compact过程的埋点器时,JVM采用指针碰撞法律法律辦法 分配内存。而使用CMS你这个 基于标记-清除(Mark-Sweep)算法的埋点器时,采用空闲列表法律法律辦法 。(下篇文章会具体介绍不同的垃圾埋点器)

  不管是指针碰撞还是空闲列表,回会 居于同另一个 问题报告 ,那这麼来越多这麼来越多 在多守护进程的场景下的守护进程安全问题报告 。多个守护进程一齐在new的并且把对象分配到同一块内存了怎莫办,不得干起来么!于是jvm采用了一种生活方案来处里:

  咦!一看字节码才知道,让让我们都的一行new的代码,对应的字节码原来愿意做不到多操作!让让我们都逐一来分析一下。

  相关链接(注:文章讲解JVM以Hotspot虚拟机为例,jdk版本为1.8,当事人技术博客www.17coding.info)

  1、 你都回会 了解的java内存管理机制-运行时数据区

  2、 你都回会 了解的java内存管理机制-内存分配

  3、 你都回会 了解的java内存管理机制-垃圾标记

  4、 你都回会 了解的java内存管理机制-垃圾回收

  引用类型变量中存储这麼来越多这麼来越多 在堆中分配的对象实例数据的地址。

      

  句柄池的法律法律辦法 会在句柄池中存放类型对象的相关信息,而直接访问的法律法律辦法 会把类型对象的信息放满实例对象的对象头中(让让我们都知道对象头包含“指向对象类型数据的指针”,着实这并全是都回会 的,让让我们都常用的HotSpot虚拟机采用的是直接指针的法律法律辦法 ,这麼来越多这麼来越多对象头中会包含“指向对象类型数据的指针”,不可能 某类虚拟机采用的是句柄的法律法律辦法 访问对象,那不可能 就不都回会 在头部存储你这个 指针了)。你这个 种法律法律辦法 都互有优缺点:

  原来的代码让让我们都或多或少这麼来越多这麼来越多 会陌生,让让我们都知道使用new关键字回会 创建另一个 对象,对应的字节码如下

  

  在上一篇文章中,让让我们都花了较大的篇幅去介绍了JVM的运行时数据区,或者重点介绍了栈区的底部形态及作用,相关内容请猛戳!在本文中,让让我们都将主要介绍对象的创建过程及在堆中的分配法律法律辦法 。

  2)、 空闲列表

  不可能 Java堆全是规整的:用过的和空闲的内存相互交错。都回会 维护另一个 列表,记录哪些内存可用。分配内存时查表找到另一个 足够大的内存,并更新列表,你这个 分配法律法律辦法 称为"空闲列表"(Free List)。这类下图,好好的一块内存被绿得乱七八糟,用里面指针碰撞的法律法律辦法 是碰不动了!这麼来越多这麼来越多就用另一个 小本本记着哪里有多大的空闲空间回会 绿!当然下图的地址编号是虚拟的,空闲列表的样子也是我意淫出来的,表达的意思你懂就行! 

      

  astore依然都回会 弹出栈顶值,或者存储到编号为1的变量中供后续使用。至此另一个 完整篇 的对象不可能 创建且返回对象内存引用给本地变量存储了。