有GC就是爽,再也不用自己清理垃圾了

Java中的“GC”是什么呢?它的英文是Garbage Collection,翻译过来就是垃圾回收,是JVM用来帮你回收Java程序中产生的垃圾的一种机制。
对于Java工程师(码农)来说,了解垃圾回收机制(GC)有哪些好处呢?首先,可以装逼,哦,不不,可以满足Java工程师(码农)求知欲;其次,可以帮你写出更好的Java应用程序。

想了解GC,你得先了解它们:

首先,来看JVM在运行时的内存图:

这里呢,咱们只说说堆内存和栈内存
堆内存:Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。你也可以这么理解,(敲黑板,往下划重点了)它是管理对象的,凡是new出来的对象,都在堆内存里。
这块内存呢,是可以调配大小的,这里有参数:
-Xms:设置JVM启动时最小的堆内存大小
-Xmx:设置JVM堆的最大内存大小
栈内存:(敲黑板,往下划重点了)一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。通过这个参数可以调配它的大小,
-Xss:这个参数就是用来指定栈的大小
这里咱们举个例子再来说明堆和栈,假如有这样两句话:
int i=10;
LovoStudent s = new LovoStudent();
它们在JVM的内存中如何分配呢?看图:

为何让大家看内存图呢?是为了说明什么是Java中的垃圾。那这个垃圾到底是什么呢?
你可以这么理解,(敲黑板,往下划重点了)凡是不被引用变量引用的对象都是垃圾。哦豁,什么意思,自己去揣摩10分钟。揣摩完回来,咱们拿上面的例子来说,还是这句话,LovoStudent s = new LovoStudent(); 我把这个堆内存中的new LovoStudent();变成垃圾怎么来写?直接写 s=null;引用变量不再引用堆内存的对象,那这个对象就是垃圾。

那么我问个智障问题,咱们所说的垃圾,会存在于JVM中哪块内存里?

垃圾回收

明白了以上的内容,垃圾回收原理就很容易理解了。
垃圾回收机制就是JVM根据一定的算法和线程调度(这里只做简单认识,感兴趣的关注朗沃博客,后续有文章会详解哪些算法和线程调度)来处理产生的垃圾。这种机制对程序员来说,比10个G的高清无码岛国动作片都来的爽,因为你不用手动释放内存了,也不用担心内存泄漏问题。在其它语言中,比如C,手动释放内存很蛋疼呐!
说到回收,不得不提Object类中的finalize()方法,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。也就是说当一个对象被当作垃圾回收时,会调用该方法。既然如此,那咱们是不是可以写个类继承一下Object(废话,你能写个类不继承自Object么),覆写finalize(),比如写个输出语句:System.out.println(“我成垃圾了,正在被回收”);来显式的看一看对象什么时候被回收的呢?完全可以。说完这个finalize()方法,还得说说System.gc()方法,这个方法又是干嘛的?运行垃圾回收器。调用 gc 方法意味着JVM做了一些努力(注意是一些努力,并不是100%,通常还是能回收的)来回收未用对象,以便能够快速地重用这些对象当前占用的内存。
说完这些前提,咱们就可以设个场景,假如你去饭馆吃饭,首先得占个桌子,占了桌子之后呢就点菜上菜,假设你是土豪,可以点很多菜,陆续上来,先上的菜一来,你一顿的胡吃海塞留下很多垃圾,后来的菜再来,可能没地方放。开饭馆的肯定考虑这个问题啊,毕竟顾客是上帝嘛,于是安排了个服务员小妹儿,不定时的在场子里巡回,来收走你吃完菜的盘子。好像这问题就解决了,但是,不排除你是个吃货,吃的太快了,小妹儿来不及巡回到你这儿,你就有很多垃圾了,此时你是不是得大喊一声,“哎,小妹儿,到这儿收空盘子”,然后小妹儿对你微微一笑,“好的,我马上来收”(当然小妹儿也可能会说“哎呀,客官稍等,马上就来”)。至于在收盘子时候你们再发生点啥,那就得看自个了⋯⋯(嘿嘿嘿⋯⋯)
好,打住,不是说好的讲GC的嘛,怎么扯到饭馆小妹儿了,咳咳⋯⋯是这样子,
饭馆——JVM
桌子——堆内存
菜——对象
空盘子等垃圾——未被引用的对象
小妹儿不定时巡回收垃圾——JVM的一定算法和线程调度回收垃圾
你喊小妹儿收盘子——调用System.gc()方法
好了,只能解释到这儿了⋯⋯
口说无凭,代码为证。写点代码验证一下:
定义一个GCTest类代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class GCTest {
private String name;
public GCTest(String name){
this.name= name;
}
//覆写finalize()方法
@Override
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
super.finalize();
System.out.println(this.name+"是垃圾,正在被回收");
}
public static void main(String[] args) {
//创建三个对象
GCTest gt1 = new GCTest("gt1");
GCTest gt2 = new GCTest("gt2");
GCTest gt3 = new GCTest("gt3");
//把对象去掉引用,变成垃圾
gt1=null;
gt2=null;
gt3=null;
//调用gc()方法,主动回收垃圾
System.gc();
}
}

运行结果留给大家去测试了⋯⋯