最近在对手机性能做了一些小概念总结,方便对于自己的个人思考
Shallow Size:
对象本身占用的内存空间,不包含其引用的对象,但在JAVA中除基本类型外,一切均为对象,也就是说持有的一直为对象的引用,如String类型对象,它主要包含3个int成员(3*4B)、1个char[]成员(1*4B)以及一个对象头(8B),尽管char[]可能指向一大块字符,但String对象里只有一个引用所占4B的空间,因此String类型对象的Shallow Size就是12B+4B+8B = 24B。
Retained Size:
对象本身的Shallow Size + 对象能直接或间接访问到的对象的Shallow Size,也就是说Retained Size就是该对象被gc之后所能回收内存的总和。
为了更好地理解Retained Size,不妨以图1加以说明,图中每个节点对应内存中的一个对象,但注意这里有个特殊的节点GC Roots(详见注解),它也是Reference chain的起点。在图3中,从对象obj1入手,可知通过obj1可以直接或间接访问的对象为蓝色节点,而左图中obj3是GC Roots可达的,也就是说断掉obj1到obj3的Reference chain后,obj3还有GC Roots的Reference chain,因而在gc时obj1被回收也不会回收obj3,因此在左图obj1的obj1的Retained Size = obj1 + obj2 + obj4 的shallow size,而右图obj1的Retained Size = obj1 + obj2 + obj4 +obj3 的shallow size.总之,Retained size是一个整体度量,能反映内存结构和对象图的依赖关系,还可以找到根节点。
图1 Retained Size示例图
注:GC Roots特指垃圾收集器对象,JVM GC时会回收那些不是GC roots且没有被GC roots引用的对象。JVM对内存中对象进行回收,主要是通过GC Roots Tracing来辨别对象是否在使用,进而进行回收。也就是说通过一系列名为“GC Roots”的对象作为起始点,从节点向下搜索,搜索过的路径称之为Reference Chain,当一个对象到GC Roots没有任何Reference Chain相连时,则表明此对象不可用,GC时将被回收(该流程的示例图见图2)。
图2.GC Roots Tracing回收机制
Heap Size:
堆的大小,当资源增加,当前堆的空间不够时,系统会增加堆的大小,若超过上限(如64M,阈值视平台而定)则会被杀掉
Allocated:
堆中已分配的大小,即App应用实际占用的内存大小,资源回收后,此项数据会变小。
关于gc过程,我们又要看一个finalize方法,可以更好的理解gc
1 的GC只负责内存相关的清理,所有其它资源的清理必须由程序员手工完成。要不然会引起资源泄露,有可能导致程序崩溃。
2 调用GC并不保证GC实际执行。 3 finalize抛出的未捕获异常只会导致该对象的finalize执行退出。 4 用户可以自己调用对象的finalize方法,但是这种调用是正常的方法调用,和对象的销毁过程无关。 5 JVM保证在一个对象所占用的内存被回收之前,如果它实现了finalize方法,则该方法一定会被调用。Object的默认finalize什么都不做,为了效率,GC可以认为一个什么都不做的finalize不存在。 6 对象的finalize调用链和clone调用链一样,必须手工构造。 如Java代码
- protected void finalize() throws Throwable {
- super.finalize();
- }
Java代码
- class C {
- static A a;
- }
- class A {
- B b;
- public A(B b) {
- this.b = b;
- }
- public void finalize() {
- System.out.println("A finalize");
- C.a = this;
- }
- }
- class B {
- String name;
- int age;
- public B(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public void finalize() {
- System.out.println("B finalize");
- }
- public String toString() {
- return name + " is " + age;
- }
- }
- public class Main {
- public static void main(String[] args) throws Exception {
- A a = new A(new B("allen", 20));
- a = null;
- System.gc();
- Thread.sleep(5000);
- System.out.println(C.a.b);
- }
- }
Java代码
- A finalize
- B finalize
- allen is 20