java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”。jvm解决的两个问题:给对象分配内存以及回收分配给对象的内存。GC:将内存中不再被使用的对象进行回收。GC的作用域是JVM运行时数据区的方法区和堆。频繁收集Young区;较少收集Old区;基本不动Perm区。

1.概述

  垃圾收集(GC)需要完成的3件事:

  (1)哪些内存需要回收?

  (2)什么时候回收?

  (3)如何回收?

  GC类型:

  (1) Minor GC:针对新生代的GC

  (2) Major GC:针对旧生代的GC

  (3) Full GC:针对永久代、新生代、旧生代三者的GC

  为什么需要了解GC和内存分配?

  当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,就需要对这些“自动化”的技术实施必要的监控和调节。

  在java内存运行时区域的各个部分中,程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭,栈中的栈帧随着方法的进入和退出而有条不紊的执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这几部分区域的内存分配和回收都具有确定性,不需要考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟着回收了。而java堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样。只有在程序处于运行期时才能知道会创建哪些对象,这部分内存的分配和回收都是动态的,垃圾收集器所关注的就是这部分内存。

2.判断对象是否已死

  (1) 引用计数法

    给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。主流的java虚拟机里面没有选用引用计数算法来管理内存,其中最主要的原因就是它很难解决对象之间相互循环引用的问题。

  (2) 可达性分析算法

    算法的基本思想就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

  在java语言中,可作为GC Roots的对象包括下面几种:

    a.虚拟机栈(栈帧中的本地变量表)中的引用的对象

    b.方法区中类静态属性引用的对象

    c.方法区中常量引用的对象

    d.本地方法栈中JNI(Native方法)引用的对象

  判断一个类是否是“无用的类”的条件为:

    a. 该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例

    b. 加载该类的ClassLoader已经被回收

    c. 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

3. 垃圾收集算法

  (1) 标记--清除

    标记清除算法是最基础的算法,算法分为“标记”和“清除”两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

    不足:一个是效率问题,标记和清除两个过程两个过程效率都不高;另一个是空间问题,标记清除之后会产生大量的不连续的内存碎片,空间碎片太多可能导致之后需要分配大量内存对象时,无法找到足够的连续的内存而不得不提前触发另一次垃圾收集动作。

    

                                

  (2) 复制算法

    将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂的情况了,实现简单,运行高效,代价为将内存缩小为原来的一半。这种方法适用于回收新生代。

               

  (3) 标记--整理算法

    标记整理算法中的标记过程与标记清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

    

  (4) 分代收集算法

    在新生代中,每次垃圾收集时都发现大批对象死去,只有少量存活,选择复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就需要使用标记清理或者标记整理的算法来回收。

4.垃圾收集器

  如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。

  (1) Serial收集器

    它的“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。适用于新生代。

  (2) ParNew收集器

    ParNew收集器就是Serial收集器的多线程版本。

  (3) Parallel Scavenger收集器

    Parallel Scavenger收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器。

  (4) Serial Old收集器

    Serial Old收集器是Serial收集器的老年代版本,它同样是一个单线程收集器,使用“标记清理”算法。

  (5) Parallel Old 收集器

    Parallel Old 是 Parallel Scavenger收集器的老年代版本,使用多线程和“标记整理”算法。

  (6) CMS 收集器

    CMS收集器是一种以获取最短回收停顿时间为目标的收集器。基于“标记清除”算法实现的。整个步骤分为:

    a. 初始标记

    b. 并发标记

    c. 重新标记

    d. 并发清除

  (7) G1收集器

    优点:并行和并发,分代收集,空间整合,可预测停顿。

5. 内存分配

  (1) 对象优先在Eden分配

    大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。

  (2) 大对象直接进入老年代

    大对象是指需要连续内存空间的java对象,最典型的大对象就是很长的字符串以及数组。经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的连续空间来“安置”它们。

  (3) 长期存活的对象将进入老年代

    虚拟机为每一个对象定义一个对象年龄计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且被Survivor容纳的话,将被移动到Survivor空间中,并设置对象年龄为1.当年龄增加到一定程度(默认为15岁),就会被晋升到老年代。

  (4) 动态对象年龄判定

    如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或者等于该年龄的对象就可以直接进入老年代,无须等到阈值年龄。

  (5) 空间分配担保

6. 内存分析工具

  (1) Jmc

    java 7u40发布中加入的性能监控工具。功能全面,包括CPU占用率、内存使用情况、I/O耗时等。常用于性能分析。

  (2) Jconsole

    jdk自带的可视化监视和管理控制台。监控某个进程的内存、线程、类等信息。可观察堆内存新生代、老年代的使用情况。

  (3) Jvisualvm

    jdk自带的可远程或本地监控内存泄漏,跟踪垃圾回收的工具。可以dump堆内存数据

  (4) Eclipse Memory Analyzer

    是分析堆数据的专业工具,可以定位内存泄漏的原因。

    

    

    

    

  

GC垃圾回收器的更多相关文章

  1. [Java基础]-- Java GC 垃圾回收器的分类和优缺点

    https://blog.csdn.net/high2011/article/details/80177473?utm_source=blogxgwz2 参考:elasticsearch实战-使用G1 ...

  2. 一篇文章让你了解GC垃圾回收器

    简单了解GC垃圾回收器 了解GC之前我们首先要了解GC是要做什么的?顾名思义回收垃圾,什么是垃圾呢? GC回收的垃圾主要指的是回收堆内存中的垃圾对象. 从根对象出发,所有被引用的对象,都是存活对象 其 ...

  3. .NET GC垃圾回收器

    GC垃圾回收器简介 全名: Garbage Collector 原理: 以应用程序的根(root)为基础,遍历应用程序堆(heap)上动态分配的所有对象,通过识别它们是否被引用来确定哪些对象是已经死亡 ...

  4. 如何获取GC(垃圾回收器)的STW(暂停)时间?

    前言 在现代的容器化和微服务应用中,因为分布式的环境和错综复杂的调用关系,APM(Application Performance Monitoring 应用性能监控)显得尤为重要,它通过采集应用程序各 ...

  5. GC(垃圾回收器)中的算法

    GC的两种判定方法 (1) 引用计数法 给对象添加一个引用计数器,每当引用一次+1,每次失效时-1,当计数器为0时,表示对象就是不可能再被使用的. (2) 可达性分析算法 将“GC Roots”对象作 ...

  6. Java虚拟机笔记(二):GC垃圾回收和对象的引用

    为什么要了解GC 我们都知道Java开发者在开发过程中是不需要关心对象的回收的,因为Java虚拟机的原因,它会自动回收那些失效的垃圾对象.那我们为什么还要去了解GC和内存分配呢? 答案很简单:当我们需 ...

  7. Android内存优化5 了解java GC 垃圾回收机制3

    引言 接App优化之内存优化(序), 作为App优化系列中内存优化的一个小部分. 由于内存相关知识比较生涩, 内存优化中使用到的相关工具, 也有很多专有名词. 对Java内存管理, GC, Andro ...

  8. 牛客网Java刷题知识点之垃圾回收算法过程、哪些内存需要回收、被标记需要清除对象的自我救赎、对象将根据存活的时间被分为:年轻代、年老代(Old Generation)、永久代、垃圾回收器的分类

    不多说,直接上干货! 首先,大家要搞清楚,java里的内存是怎么分配的.详细见 牛客网Java刷题知识点之内存的划分(寄存器.本地方法区.方法区.栈内存和堆内存) 哪些内存需要回收 其实,一般是对堆内 ...

  9. C#.Net GC(garbage Collector) 垃圾回收器

    以前一直以为gc的原理很简单,也就是分代处理堆数据,直到我的膝盖中了一箭(好吧 直到有天汪涛和我说他面试携程的面试题 关于服务器和 工作站gc 的区别)其实我当时尚不知道 工作站和服务器有什么区别更不 ...

随机推荐

  1. 【Linux】CentOs的常用命令

    1.文件目录操作命令            ls:列出当前路径下的文件或者目录列表                -l 列出详细信息                -a 列出所有的文件信息,包括隐藏文 ...

  2. Android App 安全的HTTPS 通信

    漏洞描述 对于数字证书相关概念.Android 里 https 通信代码就不再复述了,直接讲问题.缺少相应的安全校验很容易导致中间人攻击,而漏洞的形式主要有以下3种: 自定义X509TrustMana ...

  3. 如何在IIS上发布网站 在阿里云服务器windows server2012r iis上部署.net网站

    如何在IIS上发布网站   本片博客记录一下怎么用IIS发布一个网站,以我自己电脑上一个已经开发完成的网站为例: 1.打开项目 这是我电脑上的一个项目,现在我记录一下将这个项目发布到iis上的整个过程 ...

  4. H+ 添加(新增)Tab选项卡

    //注:在contabs.js文件中 $(function () { }); 方法外 加入//注: data-name="' + menuName + '" 这句是加入的自定义属性 ...

  5. Kubernetes 1.12公布:Kubelet TLS Bootstrap与Azure虚拟机规模集(VMSS)迎来通用版本号

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/82880341 https: ...

  6. python conv2d scipy卷积运算

    scipy的signal模块经常用于信号处理,卷积.傅里叶变换.各种滤波.差值算法等. *两个一维信号卷积 >>> import numpy as np >>> x ...

  7. k8s namespace/volume

    https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/ 只挑个人感觉使用较多/比较重要的点来说 ...

  8. Airtest iOS测试环境部署

    [本文出自天外归云的博客园] 简介 这个Airtest IDE是通过iOS-Tagent来操作iPhone的,你可以在Airtest IDE里录制脚本来实现自动化操作iPhone 前提 1. 得有个i ...

  9. Node.js 反序列化漏洞远程执行代码(CVE-2017-5941)

    2.1 摘要 2.1.1 漏洞介绍 漏洞名称: Exploiting Node.js deserialization bug for Remote Code Execution 漏洞CVE id: C ...

  10. java模式:建造者模式

    我发现很多源码很喜欢用这个模式,比如spring cloud,spring framework. 建造者模式(Builder)用以构建各种各样的对象,主要功能就是代替对象的构造函数,更加自由化. 举个 ...