From 349d5b0c64a6173097d07dd562cc642f5f2b9ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=B8=B8=E4=B9=90?= Date: Mon, 22 Apr 2019 15:29:46 +0800 Subject: [PATCH] =?UTF-8?q?Update=20Java=20=E8=99=9A=E6=8B=9F=E6=9C=BA.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 增加 标记——清楚算法的详细描述 * 完善 JDK 1.8 开始 方法区的描述 --- docs/notes/Java 虚拟机.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/notes/Java 虚拟机.md b/docs/notes/Java 虚拟机.md index a6b39e64..56db4110 100644 --- a/docs/notes/Java 虚拟机.md +++ b/docs/notes/Java 虚拟机.md @@ -88,6 +88,8 @@ java -Xms1M -Xmx2M HackTheJava HotSpot 虚拟机把它当成永久代来进行垃圾回收。但很难确定永久代的大小,因为它受到很多因素影响,并且每次 Full GC 之后永久代的大小都会改变,所以经常会抛出 OutOfMemoryError 异常。为了更容易管理方法区,从 JDK 1.8 开始,移除永久代,并把方法区移至元空间,它位于本地内存中,而不是虚拟机内存中。 +方法区是一个 JVM 规范,永久代与元空间都是其一种实现方式。在 JDK 1.8 之后,原来永久代的数据被分到了堆和元空间中。元空间存储类的元信息,静态变量和常量池等放入堆中。 + ## 运行时常量池 运行时常量池是方法区的一部分。 @@ -224,8 +226,11 @@ obj = null;

+在标记阶段,程序会检查每个对象是否为活动对象,如果是活动对象,则程序会在对象头部打上标记。 -标记要回收的对象,然后清除。 +在清除阶段,会进行对象回收并取消标志位,另外,还会判断回收后的分块与前一个空闲分块是否连续,若连续,会合并这两个分块。回收对象就是把对象作为分块,连接到被称为“空闲链表”的单向链表,之后进行分配时只需要遍历这个空闲链表,就可以找到分块。 + +在分配时,程序会搜索空闲链表寻找空间大于等于新对象大小 size 的块 block。如果它找到的块等于 size,会直接返回这个分块;如果找到的块大于 size,会将块分割成大小为 size 与 (block - size) 的两部分,返回大小为 size 的分块,并把大小为 (block - size) 的块返回给空闲链表。 不足: