java虚拟机(第二版) 第二章总结

Posted up随想

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java虚拟机(第二版) 第二章总结 相关的知识,希望对你有一定的参考价值。

本文总结下java虚拟机的第二章的第三小节


1、(原文2.3)HotSpot虚拟机对象探秘


文中以HotSpot虚拟机为例,讲述了java对象的创建以及访问。


当我们写的new关键字被虚拟机执行时:

 <1>、检查new所对应的参数是否能在常量池中定位到一个类的符号引用;

<2>、检查这个符号引用代表的类是否已被加载、 解析和初始化过; 

<3>、如果没有, 那必须先执行相应的类加载过程(书中第7章);

<4>、上述步骤执行结束后,则为新生对象分配内存,有两种方式:

      <1、指针碰撞:指堆内存为规整的,可以简单的分为已被占用的和未被占用的两块,中间以一个指针作为分隔,为新对象分配内存只是将指针向未被占用的内存空间移动下而已;

      <2、空闲列表:指堆内存并非规整的,虚拟机维护着一个未使用内存块的列表,当新建对象时,从列表中查找一个可以容下新对象的内存即可;

选择哪种分配方式由使用哪种垃圾收集器决定,Serial、 ParNew等带Compact(标记-整理算法)过程的收集器时, 系统采用的分配算法是指针碰撞,

CMS,基于Mark-Sweep算法(标记-清除算法)的收集器时, 通常采用空闲列表。


注:关于各个垃圾收集器所采用的算法概述如下,后续会详细总结

    Serial:复制算法(新生代)

    Serial Old:标记-整理算法(老年代)

    ParNew:(Serial的多线程版本)复制算法(新生代)

    Parallel Scavenge:(“吞吐量优先”收集器)复制算法(新生代)

    Parallel Old:(Parallel Scavenge的老年代版本)标记-整理算法 (老年          代)

CMS和G1后续会详细总结。


继续对象的创建内容总结...


<5>、解决对象创建在多线程情况下的线程安全问题的两种方案:

    <1、CAS配上失败重试的方式保证更新操作的原子性;

    <2、把内存分配的动作按照线程划分在不同的空间之中进行, 即每个线程在Java堆中预先分配一小块内存, 称为本地线程分配缓冲( Thread Local Allocation Buffer,TLAB) 。 哪个线程要分配内存, 就在哪个线程的TLAB上分配, 只有TLAB用完并分配新的TLAB时, 才需要同步锁定;

    虚拟机通过-XX: +/-UseTLAB参数设定使用TLAB。

<6>、初始化默认值;

<7>、对对象进行必要的设置, 例如这个对象是哪个类的实例、 如何才能找到类的元数据信息、 对象的哈希码、 对象的GC分代年龄等信息;

2、(原文2.3.2)在HotSpot虚拟机中, 对象在内存中的布局分为3块区域: 对象头( Header) 、实例数据( Instance Data) 和对齐填充( Padding) 。此部分都是些硬知识,且不常见,故暂时未总结,感兴趣的读者可以阅读原书。


3、(原文2.3.3) 对象的访问定位


主流的访问方式有使用句柄和直接指针两种。

<2>直接指针:看图我就不说话了


好处是速度更快, 节省了一次指针定位的时间开销,且因对象访问在Java中超级频繁, 所以会节省一大笔时间;


HotSpot是使用直接指针来访问对象的


本节完。


以上是关于java虚拟机(第二版) 第二章总结 的主要内容,如果未能解决你的问题,请参考以下文章

精选资源深入理解Java虚拟机(第二版).pdf

深入理解java虚拟机第二版类文件结构

Java内存区域 - 深入Java虚拟机读后总结

Java内存区域 - 深入Java虚拟机读后总结

Java虚拟机体系结构深入研究总结

Java虚拟机体系结构深入研究总结