深入理解JVM与GC回收
JVM内存模型
java虚拟机在执行java程序的过程中会把它所管理的内存划分为不同的若干个不同的的数据区域,这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机的进程的启动而存在,有些区域依赖用户线程的启动和结束而创建和销毁,java虚拟机所管理的内存将会包括以下几个运行时数据区域

JVM分为堆区和栈区,还有方法区,初始化对象放在堆里面,引用放在栈里面,class类信息常量池(static常量和static变量)等放在方法区
- 方法区:主要是存储类信息,常量池(static常量和static变量),编译后的代码(字节码)等数据
- 堆:初始化的对象,成员变量(那种非static的变量),所有的对象实例和数组都要在堆上分配
- 栈:栈的结构是栈帧组成的,调用一个方法就压入一针,针上面存储着局部变量表,操作数栈,方法出口等信息,局部变量表存放的是8大基础类型加上一个应用类型,所以还是一个指向地址的指针
- 本地方法栈:主要为native方法进行服务
- 程序计数器:记录当前线程执行的行号
java内存分配
- 基础数据类型直接在栈空间分配
- 引用数据类型,需要new关键字来创建即在栈空间分配一个地址空间,又在堆空间分配对象的类变量
- 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收
- 方法的引用参数,在栈空间分配一个地址空间,并指向并指向堆空间的对象区,当方法调用完成后从栈空间回收,堆空空间区域等待GC回收
- 方法调用时传入的实际参数,先在栈空间分配,在方法调用完成后从栈空间释放
- 局部变量NEW出来时,在栈空间和堆空间分配空间,当局部变量生命周期后,栈空间立刻回收,堆空间等待GC会后
- 字符串常量在DATA区域分配,this在堆空间分配
- 数组即在栈空间分配数组名称,又在堆空间分配数组的实际大小
GC的两种判定方法
引用计数法
给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。
引用计数算法原理简单,实现容易,但是缺点是不能解决对象间循环引用问题,可能会造成内存泄漏。
可达性分析算法
这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连,用图论的话来说,就是从GC Roots到这个对象不可达时,则证明此对象是不可用的。
如下图所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。

在java语言中,可作为GC Roots的对象包括下面几种:
- 虚拟机栈栈帧中本地变量表中引用的对象。
- 方法区中常量引用的对象
- 方法区中类静态属性引用的对象
GC的三种收集算法
标记清除
最基础的收集算法是“标记-清除”(Mark-Sweep)算法,如同它的名字一样,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。
之所以说它是最基础的收集算法,是因为后续的收集算法都是基于这种思路并对其不足进行改进而得到的。它的主要不足有两个:一个是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

复制算法
现在虚拟机都采用这种方法来回收新生代,将内存中新生代分为Eden和两块较小的Survivor空间,每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor中还存活的对象一次性的复制到另外一块Survivor空间上,最后清理掉Eden和用过的Survivor空间。Eden区和Survivor区的大小比值为8:1
标记整理
根据老年代的特点,出现了一种标记整理算法,同标记清除算法一样,但是后续步骤不是直接可回收对象进行清理,而是让所有存活对象向一端移动,然后直接清理掉端边界以外的内存。

GC收集器
串行收集器:串行收集器使用一个单独的线程进行收集,GC时服务有停顿时间
并行收集器:回收中使用多线程来来执行
CMS收集器:基于标记清除算法实现的,经过多次标记才会被清除。
G1收集器:从整体来看是基于“标记整理算法”来实现的收集器,从局部(两个Region之间)上来看是基于“复制算法”来实现的。CMS是一种以最短停顿时间为目标的收集器,响应优先选择CMS,吞吐量高选择G1
深入理解JVM与GC回收的更多相关文章
- 深入理解JVM——关于垃圾回收
关于垃圾回收 仿佛来自上海居委会大妈的灵魂拷问:“你是什么垃圾?” 不 今天我们要说的是JVM的垃圾回收 假如我是一个“人”类的“对象”,也和人的生命一样必有一死,可是“我真的还想再活500年~~”, ...
- 深入理解JVM+G1+GC.pdf (中文版带书签)
目录 序 VII前言 IX 第1章 JVM & GC基础知识 11.1 引言 21.2 基本术语 31.2.1 Java相关术语 41.2.2 JVM/GC通用术语 241.2.3 G1涉及术 ...
- JVM之GC回收信息详解
一.-XX:+PrintGCDetails 打印GC日志 参数配置:-Xms10M -Xmx10M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+Pr ...
- 深入理解JVM一垃圾回收算法
我们都知道java语言与C语言最大的区别就是内存自动回收,那么JVM是怎么控制内存回收的,这篇文章将介绍JVM垃圾回收的几种算法,从而了解内存回收的基本原理. 一.stop the world 在介绍 ...
- 深入理解JVM(六) -- GC执行原则和方案
上篇文章中,我们了解了Java虚拟机垃圾回收的思路和策略,这篇文章我们将了解Java是如何实现高效的回收算法的. 我们需要了解,内存回收必须要保证“一致性”,意思就是在执行GC分析的时候,系统看起来要 ...
- 深入理解JVM——虚拟机GC
对象是否存活 Java的GC基于可达性分析算法(Python用引用计数法),通过可达性分析来判定对象是否存活.这个算法的基本思想是通过一系列"GC Roots"的对象作为起始点,从 ...
- 深入理解JVM(五) -- 垃圾回收算法
上篇文章我们了解到哪些内存区域和哪些对象可以被回收,这篇文章我们就来了解一下具体的垃圾回收算法的思路,不讨论具体的实现. 一 最基础算法 标记-清除(Mark-Swap) 为什么说他是最基础的算法,因 ...
- 理解JVM之垃圾回收
1.垃圾收集算法 1) 标记-清楚算法:该算法是最基础的收集算法,其分为标记与清除两个阶段.首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,该算法主要有两个不足:一个是效率问题,标 ...
- Java虚拟机(JVM)与垃圾回收机制(GC)的详解
一.JVM结构 根据<java虚拟机规范>规定,JVM的基本结构一般如下图所示: 从左图可知,JVM主要包括四个部分: 1.类加载器(ClassLoader):在JVM启动时或者在类运行时 ...
随机推荐
- SqlServer代理(已禁用代理xp)
SqlServer 本地库作业管理的时候已禁用,将其修改为可使用,master数据库下执行以下语句: sp_configure 'show advanced options', 1; GO REC ...
- THUSC2018退役预定
Day-inf \(HNOI,CTSC,APIO\)都爆炸了之后 好不容易找回自信心,怀着一定报不上的心情报了清华 居然报上了怕不是报了的都通过了 毕竟\(wc\)的时候被清华虐惨了 还是很虚的 Da ...
- html5 表单 填表 select 下拉 textarea多行文本 output Js计算结果
<select> 下拉 <select>下有很多属性 name 其实有name就有value了,因为button提交的都是? name=value的格式, ...
- IEC62304开发过程框架
软件开发计划的任务 制定整体软件开发计划 制定设计和开发计划 规划软件开发的工具.标准和方法(Class C) 制定软件集成和集成计划 制定软件验证计划 制定软件风险管理计划 制定配置管理计划 软件需 ...
- Integer 和 int 值比较
int 是基本数据类型,会进池,可以使用 == 判断两个值相等 Integer是对象,比较对象不能使用 == , 可以使用Integer.intValue()将取出对象值比较
- WebAPI应用问题整理
这两天在实现一个WebAPI的服务过程中遇到了下面的一些问题 1, 一个Controller中添加多个Action 基于模板创建WebAPI项目后,项目中会自动生成一个ValueController的 ...
- ZOJ Problem Set – 2321 Filling Out the Team
Time Limit: 2 Seconds Memory Limit: 65536 KB Over the years, the people of the great city of Pi ...
- MySQL经典错误
本文目录: Top 1:Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行)Top 2:(主从复制报错类型)Top 3:MySQL安装过程中的报错Top 4:数 ...
- 三年Linux运维工作总结教训
Linux运维一定要知道的六类好习惯和23个教训,避免入坑! 从事运维三年半,遇到过各式各样的问题,数据丢失,网站挂马,误删数据库文件,黑客攻击等各类问题. 今天简单整理一下,分享给各位小伙伴. 一. ...
- 10分钟开始.Net Core
.Net Core 2.0发布了,API也越来越多.此时不用.Net Core,更待何时? 安装.Net Core SDK 首先,我们当然要先装.Net Core SDK,在这里下载( ...