
深入理解Java虚拟机
超频化石鱼
这个作者很懒,什么都没留下…
展开
-
判断对象存活:可达性分析算法
判断对象存活,常用的方式是引用计数器:每当对象被一个地方引用,计数器便+1;当引用失效时,计数器-1。当对象的计数器为0时,该对象便是一个不被使用的对象,即“死亡”。引用计数器实现简单,效率高。然而难以解决对象之间相互循环引用的问题(两个失效对象相互保存了对方的指针)。故JVM判定对象是否存活,并没有使用引用计数器,而是使用可达性分析算法。可达性分析算法即:有一系列“GCRoots”起点,从这些点...原创 2018-02-27 15:40:53 · 1241 阅读 · 0 评论 -
JVM对象内存布局
HotSpot虚拟机中,对象在内存中的存储布局分3部分:对象头,实例数据,对齐填充。一. 对象头对象头包含两部分信息:对象的运行时数据和类型指针。1. 对象的运行时数据对象的运行时数据非常多,主要有哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等。① 哈希码:对象的标识。② GC分代年龄:GC即Java的垃圾回收机制。Java堆分两部分:新生代堆和老...原创 2018-02-26 08:45:23 · 343 阅读 · 0 评论 -
Java对象创建过程
1. 用户new一个对象。2. JVM检查常量池,看是否可定位到一个类(所对应的符号引用),并检查该类是否已经加载,解析和初始化。若没有,则执行类加载过程。3. 类加载检查通过,JVM为新对象分配内存。由于类已经加载完成,所以内存大小是可以确定的。分配过程就是从Java堆中划分一块内存出来。JVM维护了一个空闲内存列表,记录了所有可用的内存块。分配时划分一块足够大的内存出来。这称...原创 2018-02-26 08:44:34 · 268 阅读 · 0 评论 -
Java堆,方法区,直接内存
Java的内存区中,为线程共有的有三部分:Java堆,方法区,直接内存。其中方法区中包含运行时常量池。直接内存并不属于Java的常规内存区。1. Java堆是被所有线程共享的一块内存,在启动虚拟机时创建。通常,所有的对象实例及数组都要在堆上分配。但并不绝对。2. Java堆可扩展。其内存在物理上可以不连续。当Java堆无法再扩展时,将抛出内存不足异常。3. Java的垃圾收集器主...原创 2018-02-26 08:44:01 · 424 阅读 · 0 评论 -
程序计数器,虚拟机栈和本地方法栈
Java的内存区中,为线程私有的有三部分:程序计数器,虚拟机栈,本地方法栈。1. Java虚拟机的程序计数器用于指定程序所执行字节码的行号。2. Java的多线程是用时间片轮转的方式实现的。每个线程都有自己的程序计数器,称之为线程私有,用于轮转到自己时从上次执行位置继续执行。3. 每个线程执行时,都会创建一个栈,称为虚拟机栈。而每个方法在执行时,需要存储变量表,操作数,动态链接和...原创 2018-02-26 08:42:46 · 1236 阅读 · 0 评论 -
垃圾收集器
针对于具体的情况,JVM使用不同的垃圾收集器。按照不同分代,HotSpot使用了七种垃圾收集器:① 新生代:Serial,ParNew,Parallel Scavenge② 老年代:CMS,Serial Old(MSC),Parallel Old③ 通用:G1 如图。连线表示可搭配使用。1. Serial收集器Serial...原创 2018-02-27 15:44:02 · 172 阅读 · 0 评论 -
垃圾回收时的安全点与安全区
垃圾回收时,首先要枚举所有GC Roots节点。然而枚举GC Roots节点是需要停顿执行系统的。执行系统的停顿不可以过久,否则会影响整个系统的执行。为了能快速计算出对象内什么偏移量上是什么类型的数据,从而迅速完成枚举,HotSpot使用OopMap。OopMap是个Map,记录了所有必要信息的具体地址。 然而,OopMap是需要空间的。若每一条指令都创建一个对应的OopMa...原创 2018-02-27 15:42:57 · 541 阅读 · 0 评论 -
垃圾回收算法
1. 标记-清除算法首先标记出所有需要回收的对象,标记完成后统一回收所有标记对象。该算法是最基础的回收算法。主要问题是:标记和清除的效率不高;标记清除后会产生大量不连续内存碎片,以至于程序要分配大内存时无法找到足够的连续内存,从而不得不提前触发下一次垃圾清理。2. 复制算法将内存划分为容量相等的两块。每次只使用一块。当内存1用完时,就把所有活着的对象顺序复制到内存2上,然后对内存1进行...原创 2018-02-27 15:42:23 · 184 阅读 · 0 评论 -
常量池垃圾回收:判断类的存活
方法区中的常量池也需要进行垃圾回收。主要回收对象是废弃的常量和无用的类。其中,判断类的存活需要同时满足以下3个条件:1. 该类所有的实例已经被回收,即Java堆中已经不存在任何该类的实例。2. 加载该类的ClassLoader已经被回收。3. 该类对应的java.lang.Class对象没有在任何地方被引用,即无法在任何地方通过反射访问该类的方法。同时满足这3个条件的类,就是可回...原创 2018-02-27 15:41:34 · 1049 阅读 · 0 评论 -
对象的访问定位
Java栈的本地变量表中,存储着一个reference数据,其中存储着一个引用。reference就是用来操作堆上的具体对象的。而一个引用如何定位和访问堆中对象的具体位置,有两种方式:句柄和直接指针。1. 句柄Java堆中划分一块内存作为句柄池。reference存储了对象的句柄地址。而句柄中就包含了对象实例数据等具体的地址信息。当对象被移动时,只会修改句柄中的实例数据指针。referenc...原创 2018-02-26 08:45:56 · 253 阅读 · 0 评论