
深入理解Java虚拟机
Korbin Luo
这个作者很懒,什么都没留下…
展开
-
运行时数据区
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途以及创建和销毁的时间,有的区域随着虚拟机进行的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。根据《Java虚拟机规范(Java SE 7版)》的规定,Java虚拟机所管理的内存将会包含以下几个运行时数据区域: 程序计数器(Program C...原创 2018-10-01 11:24:00 · 1179 阅读 · 0 评论 -
垃圾收集器常用参数
UseSerialGC 虚拟机运行在Client 模式下的默认值,打开此开关后,使用Serial + Serial Old 的收集器组合进行内存回收 UseParNewGC 打开此开关后,使用ParNew + Serial Old 的收集器组合进行内存回收 UseConcMarkSweepGC 打开此开关后,使用ParNew + CMS + Serial Old 的...原创 2019-02-12 16:35:45 · 440 阅读 · 0 评论 -
理解GC日志
33.125:[GC[DefNew:3324K->152K(3712K),0.0025925 secs]3324K->152K(11904K),0.0031680 secs]100.667:[Full GC[Tenured:0K->210K(10240K),0.0149142 secs]4603K->210K(19456K),[Perm:2999K->2999K...原创 2019-02-12 16:28:10 · 1243 阅读 · 0 评论 -
G1(Garbage First)收集器
G1收集器于JDK 7u4版本正式推出,是一款面向服务端应用的垃圾收集器,与其他收集器相比,G1有具备以下特点: (1) 并行与并发:G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU或CPU核心来缩短Stop-The-World停顿的时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行; ...原创 2019-02-12 15:25:14 · 864 阅读 · 0 评论 -
垃圾收集器
Parallel:并行,指多条垃圾收集线程并行工作,但此时用户线程仍处于等待状态; Concurrent:并发,指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序仍在继续运行,而垃圾收集程序运行于另一个CPU上; HotSpot包含的所有虚拟机如下图所示: 如果两个收集器之间存在连线,就说明它们可以...原创 2019-02-11 18:43:19 · 209 阅读 · 0 评论 -
HotSpot的算法实现
HotSpot使用一组称为OopMap的数据结构,在类加载完成的时候把对象内什么偏移量上是什么类型的数据计算并存储在OopMap中,同时在JIT编译过程中在特定的位置记录下栈和寄存器中哪些位置是引用记录在OopMap中,以便在GC扫描时直接从OopMap中获取出所有引用位置,快速且准确地完成GC Roots枚举。 HopSpot并没有为每条指令都生成OopMap,...原创 2019-02-11 14:24:48 · 548 阅读 · 0 评论 -
垃圾收集算法
标记-清除算法(Mark-Sweep):首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。标记方式参考《判断对象是否存活》标记-清除算法是最基础的收集算法,因为后续的收集算法都是基于这种思路并对其不足进行改进而得到的,主要不足有两点:(1) 效率低,标记和清除两个过程的效率都不高;(2) 空间问题,标记清除后会产生大量不连续的内存碎片,可能会导致后续要分配较大内存时触发另...原创 2018-11-15 14:47:44 · 188 阅读 · 0 评论 -
判断对象是否存活
引用计数算法(Reference Counting):给对象添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器值减1;任何时刻计数器为0的对象就是不可能再被使用的。优势:高效缺陷:很难解决对象之间的循环引用问题,例如objA.instance = objB及objB.instance = objA,如果除此之外这两个对象再无任何引用,实际上这两个对象已经不可能再被...原创 2018-10-24 17:54:15 · 442 阅读 · 0 评论 -
对象的访问定位
Java程序需要通过栈上的reference数据来操作堆上的具体对象,但虚拟机规范并没有定义这个引用应该通过何种方式去定位、访问堆中的对象的具体位置,所以对象访问方式也是取决于虚拟机实现而定的,目前主流的访问方式有使用句柄和直接指针两种。 使用句柄访问时,堆中会划分出一块内存来作为句柄池,虚拟机栈中存储的对象引用实际上是句柄地址,而句柄包含了对象实例数据与类型数据...原创 2018-10-01 17:53:43 · 205 阅读 · 0 评论 -
对象在内存中的存储布局
对象头中的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit,官方称它为“Mark Word”。对象需要存储的运行时数据很多,其实已经超出了32位、64位Bitmap结构所能记录的限度,但是对象头信息是与对象自身定义的数据无关的额外存储成本,考虑到虚拟机的空...原创 2018-10-01 15:52:28 · 2626 阅读 · 0 评论 -
对象创建过程
(1) 虚拟机接收到一条new指令时,先去虚拟机中检查这个指令的参数是否能在常量池中定位到一个类的符号引用,即类有没有被加载到方法区;(2) 若类未被加载到方法区,则先进行类加载,若类已被加载,则继续;(3) 获取被加载的类的对象长度;(4) 确认是否在TLAB中分配内存,若是,则在TLAB中分配内存,否则在EDEN中分配内存;(5) 将分配到的内存空间设置为零值;(6) 设置对象的...原创 2018-10-01 15:13:20 · 1280 阅读 · 0 评论 -
内存分配规则
Minor GC: 从年轻代空间(包括Eden和Survivor区域)回收内存被称为Minor GC: (1) 当JVM无法为一个新的对象分配空间时会触发Minor GC,比如当Eden区满了,所以分配率越高,越频繁执行Minor GC; (2) 内存池被填满的时候,其中的内容全部会被复制,指针会从0开始跟踪空闲内存。Eden和Sur...原创 2019-02-12 18:17:21 · 1222 阅读 · 0 评论