Android程序优化-----JAVA类的生命周期

前言:

虚拟机、类在内存中干了什么?这是对程序优化的前提知识吧!想写个程序优化的系列文章,主要写的通俗些让人一看就懂,当然严谨性就降低了。毕竟我不太可能开发虚拟机嘛!如果要自己研究还是看《深入理解Java虚拟机》这本神书吧。吐三升血来推荐这本书,这本书把.class文件、虚拟机构造、如何执行、如何优化讲的淋漓尽致。


虚拟机构造:

运行时数据区域(JAVA虚拟机在内存中划分的几个区域):

你想想啊!我们写的.java文件编译后形成.class文件。java中的类名A、方法名、常量CONSTANT和方法中的逻辑会全部映射到.class文件中,而加载.class文件到虚拟机内存中,内存中肯定也会存储这些信息。那么内存中是在那里存储这些信息呢? 实际上这个过程就是层层筛检,将人类易理解的冗余信息---》到机器能理解的极端简洁信息0101。

示例:

	public class A{
		private int a = 3;
		public static final int CONSTANT = 32;
	}

	public class B{
		static{
			System.out.println(A.CONSTANT);
			}
	}

1.堆(heap)

占内存最大的一块。存储信息

a)类对象的字段值:如A类对象a属性的值3。(对象不同而字段数值不同的信息,所以CONSTANT不在这里存储,因为所有的A类对象都只有一个值32)

b)方法区中存储该类不变信息的地址(A类对象不变化的信息是:字段名称a,类名称A,修饰符private。你有N个对象,类的字段名称也不会变嘛)

2.方法区(Method Area)

存储信息:

a)类不变信息:字段名称a,类名称A,修饰符private

b)运行时常量池(Runtime Constant Pool)用于存储编译期间生成的符号引用、字面常量。 (比如说.class文件字节码中用#1代表CONSTANT属性值3)

//-----------------------------以上是线程公有的-------------------------

3.JAVA虚拟机栈

栈中有栈帧(Stack Heap),存储局部变量表、操作栈、动态链接、方法出口等信息

4.本地方法栈

和虚拟机栈类似,只是描述的是修饰符为native的本地方法。

5.直接内存

6.程序计数器

记录程序进行到字节码行数。



要优化,就得先知道类在内存中怎么运行的。

类生命周期:

 加载(Loading)--》验证(Verification)--》准备(Preparation)---》解析(Resolution)--》初始化(Initiation)---》使用(Using)----》卸载(Unloading)。 其中标黄的验证---》准备---》解析被称为连接(Linking)。

(Android自带的proGuard有个功能叫做preVerification,Android上这个功能是被屏蔽的。在Java Micro Edition 和 Java 6把验证给分开了,在编译期间就可以进行预验证(preVerification))

其中加载和连接阶段是不会执行我们写的代码的(除非你重写类加载器),初始化阶段才开始。

加载:

1)通过类的全限定名(包名+类名)获取此类的二进制文件

2)类的静态存储结构(.class文件中描绘的方法、字段、修饰符)转换为 方法区 运行时数据结构

3)在Java堆中生成一个代表改类的java.lang.Class对象,作为方法区的访问入口


JAVA常量static加上final,则编译期间直接用32代替CONSTANT。换句话说在B的运行中没有加载A类,来读取CONSTANT变量,而是引用了B自身的常量池CONSTANT。这样就省内存,因为没有加载A类。


在java字节码中:带final

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。