diff --git a/notes/Java 虚拟机.md b/notes/Java 虚拟机.md index 5f5f8bf7..8388a0ea 100644 --- a/notes/Java 虚拟机.md +++ b/notes/Java 虚拟机.md @@ -27,9 +27,7 @@ # 一、运行时数据区域 -

- -注:白色区域为线程私有,蓝色区域为线程共享。 +

## 程序计数器 @@ -39,6 +37,8 @@ 每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。 +

+ 可以通过 -Xss 这个虚拟机参数来指定一个程序的 Java 虚拟机栈内存大小: ```java @@ -56,6 +56,8 @@ java -Xss=512M HackTheJava 与 Java 虚拟机栈类似,它们之间的区别只不过是本地方法栈为本地方法服务。 +

+ ## Java 堆 所有对象实例都在这里分配内存。 @@ -72,11 +74,11 @@ java -Xss=512M HackTheJava - From Survivor - To Survivor -

+

-Java 堆不需要连续内存,并且可以通过动态增加其内存,增加失败会抛出 OutOfMemoryError 异常。 +Java 堆不需要连续内存,并且可以动态增加其内存,增加失败会抛出 OutOfMemoryError 异常。 -可以通过 -Xms 和 -Xmx 两个虚拟机参数来指定一个程序的 Java 堆内存大小,第一个参数设置最小值,第二个参数设置最大值。 +可以通过 -Xms 和 -Xmx 两个虚拟机参数来指定一个程序的 Java 堆内存大小,第一个参数设置初始值,第二个参数设置最大值。 ```java java -Xms=1M -Xmx=2M HackTheJava @@ -123,6 +125,8 @@ objB.instance = objA; 通过 GC Roots 作为起始点进行搜索,能够到达到的对象都是都是可用的,不可达的对象可被回收。 +

+ GC Roots 一般包含以下内容: 1. 虚拟机栈中引用的对象 @@ -132,7 +136,7 @@ GC Roots 一般包含以下内容: ### 3. 引用类型 -无论是通过引用计算算法判断对象的引用数量,还是通过可达性分析算法判断对象的引用链是否可达,判定对象是否存活都与“引用”有关。 +无论是通过引用计算算法判断对象的引用数量,还是通过可达性分析算法判断对象的引用链是否可达,判定对象是否存活都与引用有关。 Java 对引用的概念进行了扩充,引入四种强度不同的引用类型。 @@ -150,7 +154,7 @@ Object obj = new Object(); 用来描述一些还有用但是并非必需的对象。 -在系统将要发生内存溢出异常之前,将会对这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出溢出异常。 +在系统将要发生内存溢出异常之前,将会对这些对象列进回收范围之中进行第二次回收。 软引用主要用来实现类似缓存的功能,在内存足够的情况下直接通过软引用取值,无需从繁忙的真实来源获取数据,提升速度;当内存不足时,自动删除这部分缓存数据,从真正的来源获取这些数据。 @@ -211,20 +215,20 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。 ### 1. 标记 - 清除 -

+

将需要回收的对象进行标记,然后清除。 不足: 1. 标记和清除过程效率都不高 -2. 会产生大量碎片,内存碎片过多可能导致无法给大对象分配内存 +2. 会产生大量碎片,内存碎片过多可能导致无法给大对象分配内存。 之后的算法都是基于该算法进行改进。 ### 2. 复制 -

+

将内存划分为大小相等的两块,每次只使用其中一块,当这一块内存用完了就将还存活的对象复制到另一块上面,然后再把使用过的内存空间进行一次清理。 @@ -234,7 +238,7 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。 ### 3. 标记 - 整理 -

+

让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。 @@ -249,13 +253,13 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。 ## 垃圾收集器 -

+

以上是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器可以配合使用。 ### 1. Serial 收集器 -

+

它是单线程的收集器,不仅意味着只会使用一个线程进行垃圾收集工作,更重要的是它在进行垃圾收集时,必须暂停所有其他工作线程,往往造成过长的等待时间。 @@ -265,7 +269,7 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。 ### 2. ParNew 收集器 -

+

它是 Serial 收集器的多线程版本。 @@ -287,7 +291,7 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。 ### 4. Serial Old 收集器 -

+

Serial Old 是 Serial 收集器的老年代版本,也是给 Client 模式下的虚拟机使用。如果用在 Server 模式下,它有两大用途: @@ -296,7 +300,7 @@ Serial Old 是 Serial 收集器的老年代版本,也是给 Client 模式下 ### 5. Parallel Old 收集器 -

+

是 Parallel Scavenge 收集器的老年代版本。 @@ -304,7 +308,7 @@ Serial Old 是 Serial 收集器的老年代版本,也是给 Client 模式下 ### 6. CMS 收集器 -

+

CMS(Concurrent Mark Sweep),从 Mark Sweep 可以知道它是基于标记 - 清除算法实现的。 @@ -329,7 +333,7 @@ CMS(Concurrent Mark Sweep),从 Mark Sweep 可以知道它是基于标记 - ### 7. G1 收集器 -

+

G1(Garbage-First)收集器是当今收集器技术发展最前沿的成果之一,它是一款面向服务端应用的垃圾收集器,HotSpot 开发团队赋予它的使命是(在比较长期的)未来可以替换掉 JDK 1.5 中发布的 CMS 收集器。 @@ -426,7 +430,7 @@ JVM 并不是永远地要求对象的年龄必须达到 MaxTenuringThreshold 才 ## 类的生命周期 -

+

包括以下 7 个阶段: @@ -616,7 +620,7 @@ public static void main(String[] args) { 应用程序都是由三种类加载器相互配合进行加载的,如果有必要,还可以加入自己定义的类加载器。下图展示的类加载器之间的层次关系,称为类加载器的双亲委派模型(Parents Delegation Model)。该模型要求除了顶层的启动类加载器外,其余的类加载器都应有自己的父类加载器,这里类加载器之间的父子关系一般通过组合(Composition)关系来实现,而不是通过继承(Inheritance)的关系实现。 -

+

**(一)工作过程** diff --git a/pics/0635cbe8.png b/pics/0635cbe8.png new file mode 100644 index 00000000..849c9eaf Binary files /dev/null and b/pics/0635cbe8.png differ diff --git a/pics/JNIFigure1.gif b/pics/JNIFigure1.gif new file mode 100644 index 00000000..f47f289e Binary files /dev/null and b/pics/JNIFigure1.gif differ diff --git a/pics/JVM-Stack.png b/pics/JVM-Stack.png new file mode 100644 index 00000000..e55ccf9b Binary files /dev/null and b/pics/JVM-Stack.png differ diff --git a/pics/JVM-runtime-data-area.jpg b/pics/JVM-runtime-data-area.jpg new file mode 100644 index 00000000..88f8691f Binary files /dev/null and b/pics/JVM-runtime-data-area.jpg differ