1.为什么要有GC

没有GC的世界,我们需要手动进行内存管理,但是内存管理是纯技术活,又容易出错。但是我们写码的目的是为了解决业务问题,所以可以把这种纯技术活自动化,当然自动化也是有代价的。

2.垃圾定义

把分配到堆中那些不能通过程序引用的对象称为非活动对象,也就是死掉的对象,称为垃圾

3.GC定义

我们想让内存管理变得自动化,就必须实现两件事(1)找到内存里的垃圾 (2)回收垃圾,让这块空间可以重新使用

4.常说的分代垃圾回收

经验:大部分的对象在生成之后马上就变成了垃圾,很有有对象能活的很久,分代垃圾回收利用该经验,引入了年龄的概念,经历过一次GC之后活下来的对象年龄为1岁。

分代:分代垃圾回收把对象分类成几代,针对不同的代使用不同的GCC算法,我们把刚生成的对象成为新生带对象,到达一定年龄的对象称为老年代对象。

为什么分代:将对象根据存活概率进行分类,对存活时间长的对象,可以减少扫描垃圾的时间,以及GC的频率和时长,本质:对对象进行分类,针对各个分类进行不同的垃圾回收算法,以对各算法扬长避短。

5.分代垃圾的堆结构

问题1:为什么新生代分成生成空间和幸存空间?

 想要回答上面的问题,就要知道JVM分代垃圾回收常用的GC算法复制算法。

1.将内存分均分成A、B两块内存

2.新生对象分配到A块中未使用的内存当中,当A块的内存使用完了,把A块的存活对象复制到B块

3.清理A块的所有对象

4.当B中的内存也用完了,就把存活对象全都复制到A块中

5.清理B块所有对象

6.不断循环

这个算法优点:简单高效,缺点:内存代价高,有效内存为占用内存的一半,所以我们进行优化。

优化后的GC算法:使用Eden和S0,S1三个分区,均分A/B块太浪费内存,空间比例在8:1:1,有效内存(可分配新生对象的内存)在总内存的9/10。

1.Eden+S0可以分配新生对象

2.对Eden+S0进行垃圾收集,把存活对象复制到S1,清理Eden+S0,一次新生代GC结束

3.Eden+S1可以分配新生对象

4.对Eden+S1进行垃圾收集,存活对象复制到S0,清理Eden+S1,二次新生代GC结束

5.不断循环

问题2:为什么要有survivor区?

如果没有suivivor区,Eden区没进行一次Minor C,存活对象就被送到老年代,老年代很快被填满,出发Major GC(一般Major GC会伴随着Minor GC,相当于出发了Full GC),老年代的内存空间远大于新生代,进行一次Full GC消耗的时间比Minor GC要长得多,这就消耗很多资源。

获取你可以想出一些办法来解决没有survivor区?

方案 优点 缺点
增加老年代空间 更多存活对象才能填满老年代。降低Full GC频率 随着老年代空间加大,一旦发生Full GC,执行所需要的时间更长
减少老年代空间 Full GC所需时间减少 老年代很快被存活对象填满,Full GC频率增加

问题3:为什么幸存空间分成两块大小相等的幸存空间1,2?也就是为什么suivivor区要分成两个?

原因是为了解决碎片化。分析如下:

假设:我们现在只有一个survivor区,模拟GC过程,下面的图更加形象化内存碎片的产生。

1.新建对象放在Eden中

2.Eden满了,触发一次Minor GC,Eden中的存活对象就会被移动到Survivor区

3.新建对象放在Eden中

4.Eden满了,此时Eden和Survivor区各有一些存活对象,如果此时把Eden区的存活对象硬放到Survivor区,很明显这两部分对象占用的内存是不连续的,这就导致了内存碎片化。

可能你还想说,碎片化就碎片化呗,能有多大影响?

内存碎片化风险很大,严重影响java程序的性能,堆空间被散布的对象占据不连续的内存,最直接的结果就是堆中没有足够大的连续内存空间,接下去如果程序需要为一个内存很大的对象分配空间,那就尴尬了。就像背包里所有东西都紧挨着放,这样就可能腾出一片空间放水杯,如果隔一点缝隙放一个,那么估计你的水杯就要拎着了。

所以顺理成章,应该建立两块Suivivor区,而且在执行上述GC复制算法的时候,Eden和S0活动对象复制到S1,清理S0和EDEN,之后在Eden和S1上分配对象,从而避免了内存碎片化。

6.GC算法共同解决的问题和衡量标准?想看专业深入的GC算法详解请看下次分解

问题:

如何分别出垃圾?

如何,何时搜索垃圾?

如何何时清理垃圾

标准:

吞吐量:单位时间内处理能力

最大暂停时间:GC执行过程中,应用暂停的时长

堆的使用率:堆空间的利用率,可用的堆越大,GC越快

访问的局部性:把具有引用关系的对象安排在堆中较近的位置,就能提高在缓存中读取到想利用的数据的概率。

JVM中GC浅解:垃圾回收的了解的更多相关文章

  1. 推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题(图解版)

    欢迎一起学习 <提升能力,涨薪可待篇> <面试知识,工作可待篇 > <实战演练,拒绝996篇 > 欢迎关注我博客 也欢迎关注公 众 号[Ccww笔记],原创技术文章 ...

  2. Java基础知识强化83:System类之gc()方法(垃圾回收)以及和finalize()区别

    1. System概述: System类包含一些有用的类字段和方法.它不能被实例化. 2. gc()方法:垃圾回收器 public static void gc()       调用gc方法暗示着Ja ...

  3. 巩固java(二)----JVM堆内存结构及垃圾回收机制

    前言:        我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制. 正文: 1.JVM堆内存结构   ...

  4. JVM虚拟机学习一:垃圾回收算法总结

    1.java虚拟机中涉及到的数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型. 基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某 ...

  5. JVM内存管理机制和垃圾回收机制

    JVM内存管理机制和垃圾回收机制 JVM结构 图片描述: java源码编译成class文件 class文件通过类加载器加载到内存 其中方法区存放的是运行时的常量.静态变量.类信息等,被所有线程共享 堆 ...

  6. 【Python】Python中对象管理与垃圾回收中两个很有意思的问题

    再Python中是利用引用计数来实现对象管理和垃圾回收的,即其他对象引用该对象时候,其引用计数加1,反之减1,当引用计数为0时候,被垃圾收集器回收. Python解释器对对象以及计数器的管理分为以下两 ...

  7. Java中内存泄露及垃圾回收机制

    转自:http://blog.sina.com.cn/s/blog_538b279a0100098d.html 写的相当不错滴...................... 摘  要 Java语言中,内 ...

  8. 【C# .Net GC】后台垃圾回收

    在后台垃圾回收 (GC) 中,在进行第 2 代回收的过程中,将会根据需要收集暂时代(第 0 代和第 1 代). 后台垃圾回收是在一个或多个专用线程上执行的,具体取决于它是后台还是服务器 GC,它只适用 ...

  9. JVM原理三-----GC模块,垃圾回收

    GC方法:在JVM启动时填入参数(比如:-XX:+UseConcMarkSweepGC ) 算法区分: 1.古老回收算法: Reference Counting  ,对象有一个引用,即增加一个计数,删 ...

随机推荐

  1. iOS核心笔记—源代码管理工具-GIT

    源代码管理工具-GIT 一. git 概述 1. git 简介? 什么是git? > git是一款开源的分布式版本控制工具 > 在世界上所有的分布式版本控制工具中,git是最快.最简单.最 ...

  2. .Net程序员学用Oracle系列(12):增删改查

    1.插入语句 1.1.INSERT 1.2.INSERT ALL 2.删除语句 2.1.DELETE 2.2.TRUNCATE 3.更新语句 3.1.UPDATE 3.2.带子查询的 UPDATE 3 ...

  3. “-webkit-font-smoothing”

    CSS3里面加入了一个"-webkit-font-smoothing"属性. 这个属性可以使页面上的字体抗锯齿,使用后字体看起来会更清晰舒服. 加上之后就顿时感觉页面小清晰了. 淘 ...

  4. SOCKET是什么

    一.问题的引入--socket的引入是为了解决不同计算机间进程间通信的问题 1.socket与进程的关系 1).socket与进程间的关系:socket   用来让一个进程和其他的进程互通信息(IPC ...

  5. (@WhiteTaken)设计模式学习——单例模式

    单例模式,个人理解就是,使用了这个模式,可以保证一个类只生成唯一的实例对象.就是在整个程序中,这个类只存在一个实例对象. GoF对单例模式的定义:保证一个类,只有一个实例存在,同时提供能对该实例加以访 ...

  6. 用 Lua 实现一个微型虚拟机-基本篇

    用 Lua 实现一个微型虚拟机-基本篇 目录 介绍 机器指令模拟 最终核心代码 虚拟机内部状态可视化 完整项目代码 后续计划 参考 介绍 在网上看到一篇文章 使用 C 语言实现一个虚拟机, 这里是他的 ...

  7. java泛型简单学习

    一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: //import java.util.List; public class GenericTest { public st ...

  8. 在windows搭建react-native android 开发环境总结

    1.安装必须的软件 1.Python 2    注意勾选 Add python.exe to Path,选项,这样就可以在安装完成后,不用手动去添加环境变量    安装完,打开cmd.exe,输入py ...

  9. Azure 基础:用 PowerShell 自动发布 CloudServices

    在软件的开发过程中,自动化的编译和部署能够带来很多的优势.下面我们聊聊如何自动发布云应用程序到 azure 上的 cloud services. 打包要发布的内容 首先使用 msbuild 编译 *. ...

  10. linux目录结构解析

    "/" :Linux文件系统的入口.也是最高一级的目录. "/bin":基本系统所需要的命令,功能和"/usr/bin"类似,这个目录下的文 ...