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

时间: 2024-08-11 07:39:51

Android程序优化-----JAVA类的生命周期的相关文章

【转】Java 类的生命周期详解

一. 引 言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告诉你“怎样做”,但至于“为什么这样做”却不多说,所以造成大家在基础和原理方面的知识比较匮乏,所以笔者今天就斗胆来讲一下这个问题,权当抛砖引玉,希望对在这个问题上有疑惑的朋友有所帮助,文中有说的不对的地方,也希望各路高手前来指正. 首先来了解一下jvm(java虚拟机)中的几个比较重要的内存区

Java类的生命周期详解

引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告诉你“怎样做”,但至于“为什么这样做”却不多说,所以造成大家在基础和原理方面的知识比较匮乏,所以笔者今天就斗胆来讲一下这个问题,权当抛砖引玉,希望对在这个问题上有疑惑的朋友有所帮助,文中有说的不对的地方,也希望各路高手前来指正. 首先来了解一下jvm(java虚拟机)中的几个比较重要的内存区域,这几

【转载】详解java类的生命周期

原文地址:http://blog.csdn.net/zhengzhb/article/details/7517213 引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告诉你“怎样做”,但至于“为什么这样做”却不多说,所以造成大家在基础和原理方面的知识比较匮乏,所以笔者今天就斗胆来讲一下这个问题,权当抛砖引玉,希望对在这个问题上有疑惑的朋友有所帮助,

详解java类的生命周期

最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告诉你“怎样做”,但至于“为什么这样做”却不多说,所以造成大家在基础和原理方面的知识比较匮乏,所以笔者今天就斗胆来讲一下这个问题,权当抛砖引玉,希望对在这个问题上有疑惑的朋友有所帮助,文中有说的不对的地方,也希望各路高手前来指正.        首先来了解一下jvm(java虚拟机)中的几个比较重要的内存区

JVM类加载器及Java类的生命周期

预定义类加载器(三种): 启动(Bootstrap)类加载器: 是用本地代码实现的类装入器,它负责将<Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar).由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作.扩展扩展(Extension)类加载器: 是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的.它负责将< Java_R

java类的生命周期

类的生命周期:加载.连接(验证.准备.解析).初始化.使用.卸载主动引用(有且只有)初始化: 1.new.getstatic.putstatic.invokestatic如果类没初始化,则初始化new关键字实例化对象.读取或设置一个类的静态字段(被final修饰.*已在编译期把结果放入常量池的静态字段除外).调用一个类的静态方法  2.使用java.lang.reflect包的方法对类进行发射调用的时候,如果类没有进行过初始化,则初始化 3.当初始化一个类的时候,父类没初始化,则初始化 4.当虚

java类的生命周期_机制

类的生命周期: 在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM.在程序执行中JVM通过装载,链接,初始化这3个步骤完成. 类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象.用来封装数据. 但是同一个类只会被类装载器装载以前 链接就是把二进制数据组装为可以运行的状态.   链接分为校验,准备,解析这3个阶段 校验一般用来确认此二进制文件是否适合当前的JVM(版本),

JAVA类的生命周期,以及类的初始化时机

类的生命周期从类被加载.连接和初始化开始,到类被卸载结束. 只有当类处于生命周期时,java程序才能使用它,比如 调用类的静态属性和方法.或者创建类的实列 简要介绍 1:加载  类的加载时指把类的.class文件中的二进制读入到内存中,把它存放在运行时数据区的方法区内,然后在堆区创建一个java.long.Class对象用来封装类在方法区内的数据结构.并且向java程序提供了访问类在方法区内的数据结构接口. 类的加载器并不需要某个类"首次主动使用"时在加载它,java虚拟机规范允许类加

java类的生命周期,从装载,链接,初始化到卸载,关键是何时卸载??

卸载       关于类的卸载,笔者在单例模式讨论篇:单例模式与垃圾回收一文中有过描述,在类使用完之后,如果有下面的情况,类就会被卸载: 该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例.加载该类的ClassLoader已经被回收.该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法.        如果以上三个条件全部满足,jvm就会在方法区垃圾回收的时候对类进行卸载,类的卸载过程其实就是在方法区中清空类信息,java类的整个生