标记清除法:

分为两个阶段,标记----清除

标记阶段将所有需要回收的对象做标记,然后在清除阶段将所有的标记对象回收

但是这种回收方法有很大的缺点,那就是这两个过程的的效率并不高,两个过程都是效率很低的过程

另外一个缺点就是标记清除之后,因为之前并没有移动对象,每个标记的对象在空间的各个位置,清除

之后会有很多不连续的内存,在遇到需要分配一个比较大的对象的时候,会出现虽然总量上有空间容纳,

但实际上因为这些内存不连续无法分配一个连续的较大的内存给这个较大对象的情况,而导致系统再次

触发一次GC

复制算法:

复制算法是将空间分为两个大小相等的部分,每次只使用其中的一块,然后这一块用完之后就将自己里面的

还存活着的对象复制到另一块里面去,这样的好处就是清除之后产生的内存不会出现不连续的情况,但缺点

也很明显,那就是需要将内存缩小一半,这样看来这种代价太大,所以之后的复制算法在这上面做出改进,将

内存分为了三个区域,一个Eden区域和两个survivor区域(大小为8/1/1,值得提醒的是这里所说的都是新生代),

将在回收时将Eden区域和其中一个survivor中的存活的对象复制到另一个survivor中,然后将这这两个清理,

相比于1/1的那种复制,显然这种只浪费1/10的的空间,那么这里要问了,其实我当时也提出了这样的问题,假如

存活对象是大于survivor的,那该怎么办,书上给了解释就是需要依赖其他内存来作为担保.细节先不谈,还有就是

这种复制算法,在存活对象比较多的情况下,比如老年代,效率自然就变低.所以产生了接下来这种算法

标记整理算法:

这算法之前的步骤跟第一个标记清除一样,将对象一一标记,但之后不同的是不对对象进行处理,而是将存活对象向一端移动

然后清理另一边的内存,这种算法更适用于老年代

分代收集:

其实就是因地制宜思想,在新生代这种会有大量对象死去的时候,采用复制算法,因为需要复制的内存少,而在老年代

就采用标记清理或者标记整理

垃圾收集器

收集算法不止一种,自然收集器也肯定不止一种,不同的收集器作用的范围不同,所采用的算法也不同

如果将作用范围划分为新生代和老年代的话:

连线代表两者能搭配使用,所处区域代表作用范围

依照书上画了一张简易的草图来了解这些收集器的作用范围,然后一一细说

Serial收集器

作用域:新生代

采用的收集算法:新生代Serial采用复制算法,老年代SerialOld采用标记整理

特点:单线程收集器,在进行收集的时候,需要暂停其他所有工作线程(Stop the world),简单高效,对于桌面应用场景(新生代使用内存不大)是很好的选择

缺点:在用户不可见的情况下将用户的工作线程都停掉,对其他应用造成影响

ParNew收集器

作用域:新生代

算法:新生代复制算法,老年代复制整理算法

特点:是Serial的多线程版本,其余跟Serial一样,是设置-XX:+UserConcMarksSweepGC参数默认的收集器

通过设置jvm参数为-XX:+UserParNewGC来强制使用

只有以上两种能与后面出现的并发收集器(CMS)同时工作

Parallel Scavenge收集器

作用域:新生代

采用的收集算法:复制算法

特点:多线程收集,关注点跟其他不同,他的目标是得到一个可以控制的吞吐量,即高效利用CPU时间,而其他则是尽可能缩短用户线程的停顿时间,即有良好的相应速度提升用户体验

ps:吞吐量是指运行用户代码时间/(运行用户代码时间和垃圾收集时间)

Serial Old收集器 

作用域:老年代

算法:标记整理算法

特点:两大用途,一是jdk1.5之前和与ParallelScavenge一起用,另外就是作为CMS的后备方案

Parallel Old收集器

作用域:老年代

特点:注重吞吐量和CPU资源

CMS收集器(ConcurrentMarkSweep)

作用域:老年代

算法:标记清除算法

特点:以获取最短回收停顿时间为目标

四个过程:初始标记(标记GCroot能直接关联到的对象,GC管理的主要区域是堆,所以方法区,栈,本地方法区这些不被GC管理的区域的对象一般用于做GCRoots),

并发标记(GC root Tracing),重新标记(修正因为用户操作而标记有变动的对象的标记记录),并发清除,收集过程可以和用户线程并发执行

缺点:-对CPU资源敏感,所以在跟用户进程并发执行的过程中会占用CPU资源导致应用程序变慢,吞吐量降低

-无法处理浮动的垃圾,即在运行过程中产生的垃圾(收集过程中用户进程没有停止,所以垃圾还在产生)

-标记清除,会造成空间碎片化,在大的对象产生时候内存分配会遇到麻烦

G1收集器

作用域:

算法:整体标记整理局部复制算法

特点:四大特点:

1,并行与并发,G1能利用多CPU多核心的硬件优势,来缩短STW的时间

2,分代收集

3,空间整合,上面所说的CMS的缺点就是空间碎片化,而G1采用整体标记整理局部复制算法的方法来使得空间的碎片化情况得到解决

4,可预测的停顿,建立了可以预测的停顿时间的模型,能让使用者明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒

感觉这部分知识还需要慢慢啃,一下子搬上来概念或者概述也没啥用...

java几种垃圾收集方法和垃圾收集器的更多相关文章

  1. tornado 第二种路由方法(装饰器)

    #!/usr/bin/env python # _*_coding:utf-8 _*_ import tornado.ioloop import tornado.web application = t ...

  2. 从Java虚拟机的内存区域、垃圾收集器及内存分配原则谈Java的内存回收机制

    一.引言: 在Java中我们只需要轻轻地new一下,就可以为实例化一个类,并分配对应的内存空间,而后似乎我们也可以不用去管它,Java自带垃圾回收器,到了对象死亡的时候垃圾回收器就会将死亡对象的内存回 ...

  3. 《深入理解Java虚拟机》-----第3章 垃圾收集器与内存分配策略

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来. 3.1 概述 说起垃圾收集(Garbage Collection,GC),大部分人都把这 ...

  4. JAVA 垃圾收集算法,垃圾收集器与内存分配策略(内容全面,解析简单易懂)

    垃圾收集器需要解决的三个问题: 1)哪些内存需要回收 2)什么时候回收 3)如何回收 背景:程序计数器,虚拟机栈,本地方法栈3个区域随线程而生,随线程而灭,在这几个区域内不需要过多的考虑回收的问题,因 ...

  5. 《深入理解 Java 虚拟机》读书笔记:垃圾收集器与内存分配策略

    正文 垃圾收集器关注的是 Java 堆和方法区,因为这部分内存的分配和回收是动态的.只有在程序处于运行期间时才能知道会创建哪些对象,也才能知道需要多少内存. 虚拟机栈和本地方法栈则不需要过多考虑回收的 ...

  6. JVM笔记-垃圾收集算法与垃圾收集器

    1. 一些概念 1.1 垃圾&垃圾收集 垃圾:在 JVM 语境下,"垃圾"指的是死亡的对象所占据的堆空间. 垃圾收集:所谓"垃圾收集",就是将已分配出去 ...

  7. [java] 更好的书写equals方法-汇率换算器的实现(4)

    [java] 更好的书写equals方法-汇率换算器的实现(4) // */ // ]]>   [java] 更好的书写equals方法-汇率换算器的实现(4) Table of Content ...

  8. java单例的几种实现方法

    java单例的几种实现方法: 方式1: public class Something { private Something() {} private static class LazyHolder ...

  9. Java中Map的三种遍历方法

    Map的三种遍历方法: 1. 使用keySet遍历,while循环: 2. 使用entrySet遍历,while循环: 3. 使用for循环遍历.   告诉您们一个小秘密: (下↓面是测试代码,最爱看 ...

随机推荐

  1. c# devexpress 多文档界面

    学习记录 https://blog.csdn.net/qq_25473787/article/details/81208894?utm_source=blogxgwz0

  2. linux上安装字体

    安装字体命令: yum install wqy-microhei-fonts wqy-zenhei-fonts   安装完字体的存放目录:/usr/share/fonts   默认会在fonts目录下 ...

  3. 【Django】网页跳转的问题

    这两天有个比较奇怪了问题困扰着我,就是网页跳转之后页面没有变化,虽然url已经变了,但是页面还是原来的,只是表单数据清空了 就是http://127.0.0.1:8000/signup_signin/ ...

  4. C# dns.gethostentry()获取失败,提示不存在主机

    传入参数domain有误. 如果是域名,可以解析.如果是局域ip可以解析. 如果是外网,解析不成功. 解决方法: 判断传入参数是域名还是ip,如果是域名,则使用dns.gethostentry(dom ...

  5. C语言变量声明内存分配

    转载: C语言变量声明内存分配   一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结 ...

  6. c#: 简单的日志管理类(TextWriterTraceListener)

    以c#实现轻量级的日志管理,着实简单,置一静态类记之: /// <summary> /// 日志管理 /// </summary> public static class Lo ...

  7. VMware虚拟机配置端口转发(端口映射),实现远程访问【转】

    前言本文所写的远程为各个电脑在同一个网段内 本文主要详细介绍如何远程访问虚拟机里面的项目! 机器:虚拟机(装在电脑1里).电脑1(宿主机).电脑2.电脑3.电脑4.电脑n... 操作步骤: step1 ...

  8. Js学习(6) 标准库-Array对象

    Array是Js的原生对象,同时也是一个构造函数,可以用它生成新的数组 用不用new结果都一样 var arr = new Array(2); // 等同于 var arr = Array(2); 但 ...

  9. ipv6 docker

    DOCKER, IPV6 BASIC CONFIGURATION OF DOCKER ENGINE WITH IPV6 SEPTEMBER 21, 2015 EYEPV6(AT)GMAIL(DOT)C ...

  10. 20172306 2018-2019《Java程序设计与数据结构课堂测试补充报告》

    学号 2017-2018-2 <程序设计与数据结构>课堂测试补充报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 刘辰 学号:20172306 实验教师:王志强 必 ...