Java垃圾回收机制

JVM垃圾回收不是必须的,只有在堆空间不足的时候回收。
一、首先,JVM判断对象是否存活,有两种方法
1、引用计数法
对象每被引用一次,加1。如果引用次数为零,判断对象不可再使用。会有循环引用问题
2、可达性分析法
通过一系列GC Roots对象作为起点,从这些起点开始找它的引用,它的引用的引用。如果某个对象到达不了,说明该对象不可用。

GC Roots对象可以有:
1、虚拟机栈中引用的对象。
2、方法去中类的静态属性引用的对象
3、方法区中常量引用对象
4、本地方法栈中引用的对象

二、筛选出不可达对象后,对象也不是非死不可,进行如下工作
1、第一次标记
看这些对象是否有必要执行finalize()方法,当对象没有覆盖finalize()方法或则finalize()方法被调用过后,虚拟机将这两种情况视为没有必要执行,可以回收。
2、第二次标记
如果判断对象有必要执行finalize()方法,那么这个对象会放置在F-Queue队列中,稍后会重新进行一次标记,执行finalize()方法,这时候只要对象在finalize()方法中拯救自己,比如把自己(this关键字)复制给某个类变量或者对象的成员变量,就可以避免被回收。如果还是没有逃脱,那基本上是被回收了。

三、垃圾回收算法
1、标记-清除算法
标记所有要回收的对象,清除对象。产生如下两样问题
效率不高,到了垃圾回收阶段了,要回收的对象是比不回收的要多的,遍历所有的要回收的对象,一一清除内存地址上的内容。
会产生大量不连续的内存。如果要分配大对象,无法找到足够的连续内存不得不提前触发另一次垃圾回收动作。

2、复制算法
划分两块大小相等的内存,每次只使用其中一块,这块用完了,将还活着的对象复制到另外一块,再把使用过的内存空间一次清理掉。存在的问题是只能用一块内存了。
优化的方法是,不需要1比1划分空间。因为很多对象的生命周期很短,要回收的对象是远远大于需要保留的对象,所以开辟8:1:1的内存,称作Eden和survivor,每次使用Eden和其中一块survivor空间,利用率达到90%,要回收了,把保留的对象转移到另一块survivor内存上。如果10%空间不够,需要依赖其他内存进行担保。
对象在Eden出生并经过第一次monitor GC后进入survivor,设置对象年龄为1。在survivor中每熬过一次minor GC,年龄就加1岁,当年龄加到一定程度,默认15岁时,进入老年代。

3、标记-整理算法
把保留的对象向内存的一边挪,然后直接清理掉端边界以外的内存。

新生代采用复制算法收集内存。老年代 标记-清除算法和标记-整理算法。

四、收集器
1、serial收集器 新生代 单线程 复制算法
2、serial Old收集器 老年代 标记-整理算法
3、pawNew收集器 serial收集器的多线程版本
4、parallel Scavenga收集器 新生代收集器,复制算法,关注程序吞吐量
5、parallel Old收集器的老年代版本 标记整理算法
6、CMS收集器 获取最短回收停顿时间为目标的收集器
7、G1收集器

搞定JVM垃圾回收就是这么简单

1

For example, if your computer has 128 MB of physical memory, then the maximum heap size is 64 MB, and greater than or equal to 1 GB of physical memory results in a maximum heap size of 256 MB.

The maximum heap size is not actually used by the JVM unless your program creates enough objects to require it. A much smaller amount, called the initial heap size, is allocated during JVM initialization. This amount is at least 8 MB and otherwise 1/64th of physical memory up to a physical memory size of 1 GB.

The maximum amount of space allocated to the young generation is one third of the total heap size.

最大堆是256M,初始堆大小是当前物理内存的1/64
初始堆大小 16G/64=256M
https://github.com/Snailclimb/JavaGuide/blob/master/Java相关/搞定JVM垃圾回收就是这么简单.md
Mac打印出来的GCDetails信息,

Heap
 PSYoungGen      total 76288K, used 37454K [0x000000076ab00000, 0x0000000770000000, 0x00000007c0000000)
  eden space 65536K, 57% used [0x000000076ab00000,0x000000076cf93940,0x000000076eb00000)
  from space 10752K, 0% used [0x000000076f580000,0x000000076f580000,0x0000000770000000)
  to   space 10752K, 0% used [0x000000076eb00000,0x000000076eb00000,0x000000076f580000)
 ParOldGen       total 175104K, used 0K [0x00000006c0000000, 0x00000006cab00000, 0x000000076ab00000)
  object space 175104K, 0% used [0x00000006c0000000,0x00000006c0000000,0x00000006cab00000)
 Metaspace       used 3077K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 338K, capacity 388K, committed 512K, reserved 1048576K
Process finished with exit code 0

年轻代 74.5M,其中eden 64M,survivor1和survivor2各10.5M
老年代 171M
元数据(永久代) 4.39M

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值