这是该专题Blog连载的第三部分,整理一下发上来。
-------------------------------------------------------
与垃圾收集GC相关的3件事:
1.哪些内存需要回收?
2.何时回收?
3.怎么回收?
上面3条分别对应了2部分知识:
1.垃圾收集算法(对应1)。
2.垃圾收集器(对应2、3)。
下面分别学习这些知识。
一、什么地方需要回收内存:
程序计数器、虚拟机栈、本地方法栈三个区域随线程而生,随线程而灭。每一个栈帧中分配多少内存基本上是在类结构定下来时就已知,所以这几个区域的内存分配和回收都具备确定性,方法或线程结束时,内存自然就跟随着回收了。
Java堆和方法区则不一样。只有在程序运行时才能知道会创建哪些对象,这部分内存的分配和回收是动态的,垃圾收集器关注的是这部分内存。
判断对象是否存活方法:
1、引用计数算法:给对象中添加一个引用计数器,每有一个地方引用它时,计数器的值就加1.当引用失效时计数器值就减去1.任何计数器为0的对象就是不可能再被使用的。(Java语言没有选用这个算法来管理内存,其中最主要的原因是它很难解决对象之间的相互循环引用问题)
2、根搜索算法:主流商用语言(Java、C#等)都是用根搜索算法判断对象是否存活。算法基本思路就是通过一系列名为GCRoots的对象作为起始点,从这些节点开始向下搜索,走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
Java中GC Roots对象包括:虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中的常量引用的对象、本地方法栈中JNI的引用的对象。
在根搜索中不可达的对象,处于缓刑阶段,真正宣告一个对象死亡,至少要经历两次标记过程:
(1)根搜索后发现没有与GC Roots相连接的引用链,将会被第一次标记并且进行一次筛选。筛选的条件是此对象是否有必要执行finalize()方法。如果没有覆写finalize()方法或者已经被虚拟机调用过,虚拟机视为没有必要执行finalize(),放入即将回收的集合。
(2)如果被判定为有必要执行finalize()方法,那么这个对象将会被优先放置在一个队列之中,并由虚拟机自动建立的、低优先级的finalizer线程执行(只是触发该方法,并不一定等其结束,防止出现无限循环等情况)。GC将在队列中的对象进行第二次小规模标记(标记即将回收的集合),如果把自己赋值给某个类变量或对象成员变量,将被移出即将回收的集合。
注:finalize()方法不要使用,try-finally能做所有finalize能做的工作(释放资源等)。
3、JDK1.2之后的引用:将引用分为强引用、软引用、弱引用、虚引用四种。
4、回收方法区:
在方法区进行垃圾回收的性价比一般比较低。在堆中,新生代,常规应用进行一次垃圾收集一般可以回收70%-95%的空间,而永久代的垃圾收集效率远低于此。
永久代回收两部分内容:废弃常量和无用的类。回收废弃常量与回收Java堆中的对象非常类似,即没有其他地方引用了这个字面量,在内存回收时,该常量会被系统请出常量池。
回收无用的类的3个条件:
(1)该类所有的实例都已经被回收(Java堆中不存在该类的任何实例)。
(2)加载该类的ClassLoader已经被回收。
(3)该类对应的Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
虚拟机可以对满足上述3个条件的无用类进行回收。
5、是否对类进行回收hotspot虚拟机提供参数:
-Xnoclassgc参数进行控制,还使用-verbose:class及-XX:+TraceClassLoading、-XX:+TraceClassUnLoading查看类加载和卸载信息。
大量使用反射、动态代理、CGLIB等框架的场景,以及动态生成JSP和OSGi频繁自定义ClassLoader的场景都需要虚拟机具备类卸载的功能,以保证永久代不会溢出。
二、垃圾收集算法
1、标记-清除算法:
该算法分为两个阶段,标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。
特点:最基础的收集算法。
缺点:时间问题,标记-清除的效率都不高。空间问题,清除后产生大量不连续空间的内存碎片,当程序运行需要分配大对象时无法找到足够连续的内存而不得不提前触发另一次垃圾收集动作。
2、复制算法(新生代算法):
特点:将可用内存按容量分为大小相等的2块,每次只使用其中的一块。当一块用完,就把存活的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。
缺点:将内存缩小为原来的一半。
商业虚拟机都采用复制算法来回收新生代。
新生代对象一般98%都是朝生夕死,所以将内存分为较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中的一块Survivor空间。回收时将Eden和Survivor中存活的对象一次性地拷贝到另外一块Survivor空间上,并清理掉Eden和刚才用过的Survivor空间。当存活对象大于待复制的Survivor的空间时,这些对象通过分配担保机制直接进入老年代。
3、标记-整理算法(老年代算法):
有人提出一种标记整理算法,标记过程仍然与标记清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活对象都向一端移动,然后直接清理掉端边界以外的内存。
4、分代收集算法:
一般把Java堆分为新生代和老年代。
在新生代中,每次垃圾收集是都有大批对象死去,只有少量存活,因此选用复制算法。只需付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高,没有额外空间对它进行分配担保,就必须使用标记-清理或标记-整理算法来回收。
相关推荐
### JVM学习笔记(一) #### 一、JVM概述与工具使用 JVM(Java Virtual Machine)是Java语言的核心组成部分之一,它为Java程序提供了一个跨平台的运行环境。本篇学习笔记主要介绍如何利用一系列工具来查看和监控JVM...
这个“java之jvm学习笔记五(实践写自己的类装载器)”很可能是对这一主题的详细探讨。 类装载器在Java中的主要职责是动态加载类到JVM中。Java的类装载器分为三个基本层次:启动类装载器(Bootstrap ClassLoader)、...
### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...
本篇JVM学习笔记主要涵盖了以下几个核心知识点: 1. **运行时数据区**: - **程序计数器**:记录当前线程执行的字节码的行号,用于线程恢复执行时跳转到正确位置。 - **Java虚拟机栈**:每个方法执行时创建的栈帧...
本文将深入探讨JVM中的访问控制器,主要基于“java之jvm学习笔记十一(访问控制器)-源码”这一主题,以及相关的源码分析。 首先,我们得了解Java的安全模型。Java安全模型基于一种称为安全管理器(SecurityManager)...
JVM学习笔记(缓慢更新).md
JVM的学习可以从其基本结构、代码编译和执行过程,以及内存管理和垃圾回收机制三个方面进行深入探讨。 首先,JVM的基本结构分为逻辑结构和物理结构。逻辑结构主要包括Java源码编译器、JVM执行引擎、类加载器等组件...
本篇JVM学习笔记主要关注对象声明、相关内存分配方法以及虚拟内存的物理和虚拟寻址概念。 首先,我们来看对象声明。在Java中,对象是在堆上创建的。例如,`CHeapObj` 类展示了如何在C++中模拟Java对象在堆上的分配...
**JVM学习笔记(Java虚拟机)** Java虚拟机(JVM)是Java语言的核心组成部分,它是Java程序运行的平台,负责解释和执行字节码。深入理解JVM对于优化Java应用程序性能至关重要。本笔记将从以下几个方面详细介绍JVM:...
《深入理解JVM:垃圾回收与优化》 在Java编程领域,JVM(Java Virtual Machine)扮演着至关重要的角色,它是Java程序...开发者需要不断学习和实践,才能在实际项目中有效地配置和优化JVM,确保程序的高效稳定运行。
"jvm视频及笔记"这个资源显然是一份全面学习JVM的材料,结合了视频教程和书面笔记,帮助学习者深入理解JVM的工作原理及其在实际开发中的应用。 JVM的学习可以从以下几个重要的知识点开始: 1. **JVM架构**:JVM...
这个资料包不仅涵盖了理论知识,还包含个人的学习笔记,对于学习和掌握JVM的各个方面都将大有裨益。无论是初学者还是经验丰富的开发者,都可以从中找到提升自己技能的宝贵资源。通过深入学习和实践,可以更好地理解...
### JVM学习笔记核心知识点整理 #### 一、引言与背景 随着软件开发技术的不断发展,Java作为一种广泛应用的编程语言,其背后的核心技术——Java虚拟机(JVM)的重要性日益凸显。掌握JVM不仅可以帮助开发者更好地理解...
### JVM中篇笔记知识点 #### 一、Class 文件结构 ##### 1. 概述 - **字节码文件的跨平台性** - Java 的跨平台性体现在 "Write Once, Run Anywhere" (WORA),即一次编写,到处运行。Java 语言编写的源代码在编译...
Java虚拟机(JVM)是Java程序运行的基础,它是一个抽象的计算机系统,负责执行Java字节码。本文将深入探讨JVM的工作...这本《JVM工作原理学习笔记》应包含了这些内容的详细讲解,对于学习和提升JVM相关知识极具价值。
NULL 博文链接:https://cooldatabase.iteye.com/blog/634599
Java8 Jdk JVM学习笔记、jdk1.8、SpringBoot; 主要内容为 JVM 内存与垃圾回收、类加载子系统、运行时数据区、本地方法等。适合开发1-3年想对JVM学习的同学。 在之后的开发中,更加详细的了解JVM,可以进行JVM问题...
《JVM学习笔记》 Java虚拟机(JVM)是Java平台的核心组成部分,它负责运行所有的Java应用程序。这篇笔记将深入探讨JVM的工作原理、内存管理、类加载机制以及优化策略,帮助读者全面理解JVM并提升Java程序的性能。 ...
本文将深入探讨JVM中的访问控制器,并通过分析"java之jvm学习笔记十一(访问控制器) -源码"中的`MySecurityManager`来进一步理解其工作原理。 访问控制器的主要任务是对类、方法和字段的访问进行限制,防止恶意代码...
在JVM的学习中,理解其内存模型、垃圾收集算法以及类加载机制至关重要。 1. **JVM内存模型** - **方法区**:也称为“永久代”,存储虚拟机加载的类信息、常量、静态变量等,是线程共享的区域。在Java 8之后,这...