jvm学习-GC策略

什么是GC

Garbage Collection,简称GC,本质上就是内存管理回收技术(主要指的是heap),在具体探究问题前,我们需要带着一些问题来亚就这个机制:

  • 哪些内存需要回收
  • 什么时候回收
  • 如何回收

为什么GC不需要对内存栈(stack)等其他内存区域进行管理?
这里主要是因为程序技术其、虚拟机栈以及本地方法栈的都是依附于进程存在,且分配内存的大小都是已知的,在编译过程中都已经确定好了进栈出栈的顺序。而对于堆来说,对象的内存大小是不确定的,在编译过程是不可知的,而只有在运行时才知道。

如何判断对象的有效性

引用计数法

对一个对象的引用次数进行计数,当引用次数为0时,即相当于对象已经失效,go dead了。但是jvm并没有采用这种方式。
缺点:对于引用环无法处理,a引用b,b引用a,则引用计数永不是0。

可达性分析

对于任何活着的对象,一定能追溯到其存活在堆栈或静态存储区之中的引用。从GC Root开始一直到其引用的对象,如果其间没有任何可用的引用链可达,则说明这个对象时可以回收的。

在java中可以作为GC roots包括:

  • 虚拟机栈中的本地变量表的引用对象。
  • 方法区内的静态属性引用对象。
  • 方法区内的常量引用的对象。
  • 本地方法中的JNI应用对象

垃圾收集算法

标记清除法

两阶段的清除算法:1)首先标记出需要回收的对象(可达性分析);2)标记完成后,进行一次性清除;
缺点:产生大量的不连续的内存碎片,另外就是效率比较低。

复制算法(针对对象存活率低)

新生代内存空间中对象的特点就是存活时间短。
将内存分为两块,每次使用其中的一块,将存活的对象复制到另一个部分,简单高效,缺点就是费内存。

对于jvm新生代的内存,就是采用此种方法,但是其比例则默认为8:1,首先来说新生代内存主要分为两个部分,一个eden与两个survivor空间,将其中eden和另一个survivor中的活着的对象复制到另一块survivor上,此外还有10%空间的富裕。当新生代不足的时候就会通过分配机制复制到老生代。

标记整理算法(针对对象存活率高)

复制算法在对象存活率较高的时候,效率很低,于是就标记清除变为了标记整理,首先将存活的对象向一个方向移动,将边界外的内存都清除掉。

分代收集算法

本质上就是因地制宜算法,将堆内存分成老生代和新生代,按照其特点使用合适的算法,对于新生代采用复制算法,对于老生代采用标记清除或者标记整理。

理解GC日志

[gc][young][93647][8255] duration [423ms], collections [1]/[1s], total [423ms]/[29.1m], memory [10.5gb]->[11gb]/[15.8gb],
 all_pools {[young] [1.1gb]->[1.2gb]/[1.4gb]}{[survivor] [191.3mb]->[191.3mb]/[191.3mb]}{[old] [9.2gb]->[9.6gb]/[14.1gb]}
  • young 新生代
  • old老生代
  • [1.1gb]->[1.2gb]/[1.4gb]:使用内存->GC后内存/总内存
  • total [423ms]/[29.1m]:本地GC时间/总时间
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值