JVM学习(三)JVM垃圾回收
一、引用的分类
在了解JVM垃圾回收机制之前,了解一下对象的引用类型是非常必要的。
- 强引用:GC时不会被回收
- 软引用:描述有用但不是必须的对象,在发生内存溢出异常之前被回收
- 弱引用:描述有用但不是必须的对象,在下一次GC时被回收
- 虚引用(幽灵引用/幻影引用):无法通过虚引用获得对象,用PhantomReference实现虚引用,虚引用用来在GC时返回一个通知。
二、什么是JVM垃圾回收
定义:由于Java语言没有提供释放已分配内存的显示操作方法,垃圾回收(GC)是可以自动监测对象是否超过作用域从而达到自动回收内存的一种方式。
好处:Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。
显式调用:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显式的垃圾回收调用。
PS:显式调用并不一定会立即执行,也不推荐显式调用,因为JVM有自己的垃圾回收策略。
PS:程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。(垃圾回收的不可预知性)
三、JVM垃圾回收机制
垃圾回收机制有很多种,包括:分代复制垃圾回收、标记垃圾回收、增量垃圾回收等方式。标准的Java进程既有栈又有堆。栈保存了原始型局部变量,堆保存了要创建的对象。Java平台对堆内存回收和再利用的基本算法被称为标记和清除,但是Java对其进行了改进,采用“分代式垃圾收集”。这种方法会跟Java对象的生命周期将堆内存划分为不同的区域,在垃圾收集过程中,可能会将对象移动到不同区域:
- 伊甸园(Eden):这是对象最初诞生的区域,并且对大多数对象来说,这里是它们唯一存在过的区域。
- 幸存者乐园(Survivor):从伊甸园幸存下来的对象会被挪到这里。
- 终身颐养园(Tenured):这是足够老的幸存对象的归宿。年轻代收集(Minor-GC)过程是不会触及这个地方的。当年轻代收集不能把对象放进终身颐养园时,就会触发一次完全收集(Major-GC),这里可能还会牵扯到压缩,以便为大对象腾出足够的空间。
与垃圾回收相关的JVM参数:
- -Xms / -Xmx — 堆的初始大小 / 堆的最大大小
- -Xmn — 堆中年轻代的大小
- -XX:-DisableExplicitGC — 让System.gc()不产生任何作用
- -XX:+PrintGCDetails — 打印GC的细节
- -XX:+PrintGCDateStamps — 打印GC操作的时间戳
- -XX:NewSize / XX:MaxNewSize — 设置新生代大小/新生代最大大小
- -XX:NewRatio — 可以设置老生代和新生代的比例
- -XX:PrintTenuringDistribution — 设置每次新生代GC后输出幸存者乐园中对象年龄的分布
- -XX:InitialTenuringThreshold / -XX:MaxTenuringThreshold — 设置老年代阀值的初始值和最大值
- -XX:TargetSurvivorRatio — 设置幸存区的目标使用率
四、判断一个对象是否应该被回收
1.该对象没有与GC Roots相连,则可以回收

2.该对象没有重写finalize()方法或finalize()已经被执行过则直接回收(第一次标记)、否则将对象加入到F-Queue队列中(优先级很低的队列)在这里finalize()方法被执行,之后进行第二次标记,如果对象仍然应该被GC则GC,否则移除队列。 (在finalize方法中,对象很可能和其他 GC Roots中的某一个对象建立了关联,finalize方法只会被调用一次,且不推荐使用finalize方法)
五、回收方法区
方法区回收价值很低,主要回收废弃的常量和无用的类。
如何判断无用的类:
- 该类所有实例都被回收(Java堆中没有该类的对象)
- 加载该类的ClassLoader已经被回收
- 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方利用反射访问该类
六、垃圾回收算法
GC最基础的算法有三种: 标记 -清除算法、复制算法、标记-压缩算法,我们常用的垃圾回收器一般都采用分代收集算法。
- 标记 -清除算法,“标记-清除”(Mark-Sweep)算法,如它的名字一样,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。
- 复制算法,“复制”(Copying)的收集算法,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。
- 标记-压缩算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存
- 分代收集算法,“分代收集”(Generational Collection)算法,把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。
七、垃圾回收器
- Serial收集器,串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。
- ParNew收集器,ParNew收集器其实就是Serial收集器的多线程版本。
- Parallel收集器,Parallel Scavenge收集器类似ParNew收集器,Parallel收集器更关注系统的吞吐量。
- Parallel Old 收集器,Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法
- CMS收集器,CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。
- G1收集器,G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征
JVM学习(三)JVM垃圾回收的更多相关文章
- JVM学习(三):垃圾回收算法
局部性原理和分代回收思想 大学学习操作系统或者计算机组成原理的时候都提到一个重要概念,叫局部性原理. 局部性原理是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小 ...
- JVM学习总结二——垃圾回收算法
昨天总结了JVM内存分区相关的知识,这次我们将来了解下JVM的另一个核心知识点——垃圾回收算法.这一部分其实并不太难,如果对操作系统的内存处理算法有所了解,那么这部分算法其实只看名字就能明白,两者在原 ...
- JVM学习02:GC垃圾回收和内存分配
JVM学习02:GC垃圾回收和内存分配 写在前面:本系列分享主要参考资料是 周志明老师的<深入理解Java虚拟机>第二版. GC垃圾回收和内存分配知识要点Xmind梳理 案例分析1-(G ...
- JVM学习(二):垃圾回收
我刚工作的时候问一个前辈,我们能针对JVM做出什么样的优化.前辈说,我们系统现在的性能并不需要调优,用默认的配置就能满足现在的需求了.我又问,那你为什么要看JVM相关的书呢?前辈微微一笑,悠悠地来了句 ...
- JVM实用参数——新生代垃圾回收
JVM实用参数目录 JVM实用参数——新生代垃圾回收 概述 第1部分 新生代垃圾回收介绍 第2部分 参数介绍 参考 第1部分 新生代垃圾回收介绍 本部分,我们将关注堆(heap) 中一个主要区域, ...
- JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)
转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...
- JVM系列之五:垃圾回收
. jdk1.7的堆内存 1. 堆(Java堆) 堆是java虚拟机所管理的内存中最大的一块内存区域,也是被各个线程共享的内存区域, 在JVM启动时创建,该内存区域存放了对象实例(包括基本类型的变量及 ...
- Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
- JVM(二)垃圾回收
要弄懂JVM的垃圾回收,首先要知道我们要回收什么,在哪回收,什么时候回收. 一.JVM内存模型 java虚拟机把内存模型分为了这么几部分 (1)程序计数器 程序计数器(Program Counter ...
- JVM内存管理及垃圾回收【转】
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
随机推荐
- 初学Linux (Linux_note)
根目录:/ /root: 存放root用户相关文件 /home: 存放不同用户的相关文件 /bin: 存放常用命令的目录 /sbin: 要具有一定权限才可以使用的命令 /mnt: 默认挂载光驱和软驱的 ...
- cinder 卷迁移进度的代码分析
一.cinder-api服务的入口函数 D:\code-program\cinder-ocata_cinder\cinder\api\contrib\admin_actions.py from cin ...
- SpringBoot整合SpringAdmin搭建监控平台
在SpringBoot整合Actuator进行健康监控中,胜金讲述了通过Actuator进行健康监控,但是学习API并根据API开发前端需要花费相当大的精力,本次胜金就写一下通过SpringAdmin ...
- 算法-图(3)用顶点表示活动的网络(AOV网络)Activity On Vertex NetWork
对于给定的AOV网络,必须先判断是否存在有向环. 检测有向环是对AOV网络构造它的拓扑有序序列,即将各个顶点排列成一个线性有序的序列,使得AOV网络中所有直接前驱和直接后继关系都能得到满足. 这种构造 ...
- 牛客网PAT练兵场-组个最小数
题解:从小到大输出 题目地址:https://www.nowcoder.com/questionTerminal/86ede762b450404dbab59352963378e9 /** * *作者: ...
- 为wordpress的分类以及子分类指定固定模版
在wordpress主题开发有多个不同分类页面时,通常使用category-{slug}.php的方式分别为每个分类开发不同的页面模版,slug为该分类的别名,并且无需其他设置仅仅以此命名即可. 但是 ...
- secureCRT中sftp的使用
securecrt 按下ALT+P就开启新的会话 进行ftp操作.输入:help命令,显示该FTP提供所有的命令pwd: 查询linux主机所在目录(也就是远程主机目录)lpwd: 查询本地目录(一般 ...
- 安装oracleXE快捷版(一)
yum找不到包,参考了一些文章,用iso上的包安装了.在文章后面贴有我实际的操作(黑体)和日志. 更换yum源https://www.cnblogs.com/zrxuexi/p/11587173.ht ...
- unity 对Animator动画系统的研究
unity的新动画系统叫Mecanim,使用Animator来取代旧系统Animation,按Unity文档的惯例:知识点主要分2部分:unity manual和unity script,读者可以边看 ...
- Unity 移动平台自己编写Shader丢失问题
问题一:使用AB加载资源,资源中包含有第三方shader,加载出的资源出现shader丢失的显示问题 这是因为Unity在打包的时候,会进行资源精简,默认情况下,是不会将第三方shader打包进入包体 ...