Garbage Collection
目标:理解Java的内存概念/体验Garbage Collection
本讲我们要学习Garbage Collection的知识。 | |
第一次听说Garbage Collection,什么意思呀? | |
呵呵呵,不用着急,下面我慢慢给你解释吧。 |
应用程序与内存的关系
首先来说明应用程序与内存的关系。 | |
好的,博士。 | |
以前的讲座并没有涉及到内存的问题。不过实际上在考虑到程序的性能时,与内存的概念有着密切的关系。 | |
性能……??怎么没有注意到啊。 | |
咱们以前学习的都是小程序,也不需要特别注意,但对于经常要用到的大程序等,就要注意性能这个问题了。 | |
没错啊…… |
Heap
尼克,你听说过Java模拟环境么? | |
恩…最初听说过,但是想不起来了。 | |
恩。那我再来说明一下吧。Java模拟环境就是“把Java bytecode转换成其platform的nativecode的软件”。有了它,不管在什么样的platform上面都可以运用java语言写程序了。 | |
啊~对呀,我想起来了。 | |
恩。启动Java模拟环境也就相当于启动程序了。实际上,它大体被分成了stack和heap两个区域。 对于本讲来说,重要的区域是heap。所谓heap,就相当于容纳生成对象的数据区域。 | |
也就是说,生成类的instance object的时候也渐渐形成了heap区域? | |
没错。一个Java模拟环境生成一个heap。heap区域可以自己设定自己的大小。 | |
是这样啊。在运行大的程序时,好像应该把heap的区域设定的大一些。 | |
恩,说的对!但是,尼克,如果超出了指定的heap的区域,该怎么办呢? | |
这个么……会不会出现异常? | |
对,如果超过heap的最大值,就会发生OutOfMemoryError异常,程序被中止。 |
Garbage Collection
此时Garbage Collection的存在就比较重要了。它可以把失去作用的,即不能再提供参考的instance所占用的内存区域回收,进行再利用。 | |
是这样啊 ,那么不能再作为参考的instance就是无用数据了么? | |
恩,是的。如果生成instance的内存区域不能获得释放,就会渐渐的把内存区域全部占据,最后发生OutOfMemoryError异常。 | |
总之,Garbage Collection就是将不起作用的内存进行再循环利用啊。 | |
呵呵,是的。Garbage Collection一般都是自动进行的,用户也没有必要去理会,但也可以把instance的值设为null,使其变成Garbage Collection的对象,然后就可以再利用啦! | |
我明白了。 |
体验Garbage Collection
接下来,我们来看以下的程序。 |
1
| import javax.microedition.midlet.MIDlet; | ||
2
| import javax.microedition.lcdui.Display; | ||
3
| import java.lang.Runtime; | ||
4
| |||
5
| |||
6
| public class GarbageCollection1 extends MIDlet{ | ||
7
| private Display display; | ||
8
| private Runtime runtime; | ||
9
| private final static int counter = 10000; | ||
10
| |||
11
| public GarbageCollection1(){ | ||
12
| display = Display.getDisplay(this); | ||
13
| runtime = Runtime.getRuntime(); | ||
14
| System.out.println("Total Memory = " + runtime.totalMemory() + "byte"); // Java模拟 | ||
15
| 环境中可利用的总内存容量 | ||
16
| |||
17
| for(int i=0; i<counter; i++){ | ||
18
| String string = "GarbageCollection Testing...."; | ||
19
| System.out.println("Free Memory = " + runtime.freeMemory() + "byte"); //显示空余容量 | ||
20 | } | ||
21 | } | ||
22 | |||
23
| public void startApp(){} | ||
24
| public void pauseApp(){} | ||
25
| public void destroyApp(boolean unconditional){} | ||
26
| } | ||
27
| |||
这个程序是显示heap内存的空余容量的程序。利用Runtime类中static方法中的getRuntime方法,获取Runtime对象,进而显示出可以在运行环境中使用的内存容量。 | |
恩,我明白了,实际上是利用这里获取的Runtime instance来取得内存的容量…… | |
恩,是啊。用totalMemory方法获取Java模拟环境中可以利用的总内存容量,而用freeMemory来取得空余容量。 |
runtime = Runtime.getRuntime(); |
下面就运行一下看看吧。 | |
好的! |
博士!都正常显示出来了。 | |
恩,下面咱们来找一下实际进行Garbage Collection的地方吧。 | |
是不是就是内存的空余容量被释放,也就是空余容量增加的地方啊? | |
是这样的。 |
博士!找到了!这里空余容量增加了。 | |
恩,那么这里就是进行Garbage Collection的地方。 | |
可是博士,想使用这个功能时,不能呼出Garbage Collection这个命令么? | |
当然是可以的啦!把刚才的程序做以下变更看看。 |
1
| import javax.microedition.midlet.MIDlet; | ||
2
| import javax.microedition.lcdui.Display; | ||
3
| import java.lang.Runtime; | ||
4
| |||
5
| |||
6
| public class GarbageCollection1 extends MIDlet{ | ||
7
| private Display display; | ||
8
| private Runtime runtime; | ||
9
| private final static int counter1 = 10000; | ||
10
| private final static int counter2 = 1000; | ||
11
| |||
12
| public GarbageCollection1(){ | ||
13
| display = Display.getDisplay(this); | ||
14
| runtime = Runtime.getRuntime(); | ||
15
| System.out.println("Total Memory = " + runtime.totalMemory() + "byte"); // Java模拟 | ||
16
| 环境中可利用的总内存容量 | ||
17
| |||
18
| for(int i=0; i<counter1; i++){ | ||
19
| for(int a=0; a<counter2; a++){ | ||
20 | String string = "GarbageCollection Testing...."; | ||
21 | System.out.println("Free Memory = " + runtime.freeMemory() + "byte"); //显示空 | ||
22 | 余内存容量 | ||
23
| } | ||
24
| runtime.gc(); //进行Garbage Collection | ||
25
| System.out.println("Garbage Collection!!!"); | ||
26
| } | ||
27
| } | ||
28
| |||
29
| public void startApp(){} | ||
30
| public void pauseApp(){} | ||
31
| public void destroyApp(boolean unconditional){} | ||
32
| } | ||
在这个程序中,一定时间内循环过后,利用Runtime类的gc方法,来进行Garbage Collection。 | |
那运行一下进行确认吧。 |
博士!进行Garbage Collection之后,内存就增加了! | |
恩,这样就对了。但是有一点,进行Garbage Collection,就会使处理重复进行,所以也没有必要专门进行了。 | |
好的,我知道了。 |
小结
本讲学得Garbage Collection,感觉如何呀? | |
刚开始没有听说过这个名词,以为很难,试着写程序体验后就明白了。 | |
这样就好!平常注意不到,理解了模拟环境中进行Garbage Collection后,内存被重新整理,就够了。 | |
是啊。好有趣啊。 |