序言

       笔者从事Anroid开发有些年头了,深知掌握Anroid性能优化方面的知识的必要性,这是一个程序员必须修炼的内功。在面试中,它是面试官的挚爱,在工作中,它是代码质量的拦路虎,其重要性可见一斑。在团队中,性能优化的工作又往往由经验丰富的老师傅来完成,可见要做好性能优化,绝不是一件容易的事情。

性能优化方面涉及的知识点比较广,有理论基础知识,也有实际操作技能,笔者将通过一系列的文章来进行整理,将主要包括Java虚拟机、内存分配、垃圾回收,android虚拟机、进程管理、内存优化、内存泄漏,常用内存分析及优化工具介绍等。由于笔者水平和经验有限,也是在边研究边整理,有不当之处,请不吝赐教。

当前系列内容已完成如下篇章:

【朝花夕拾】Android性能篇之(一)序言及JVM篇

【朝花夕拾】Android性能篇之(二)Java内存分配

【朝花夕拾】Android性能篇之(三)Java内存回收

【朝花夕拾】Android性能篇之(四)Apk打包

【朝花夕拾】Android性能篇之(五)Android虚拟机

【朝花夕拾】Android性能篇之(六)Android进程管理机制

前言

之所以第一篇要先介绍JVM,是因为当前Android开发的主流语言是java,而JVM又是java程序进程生命诞生的地方。JVM就像盘古一样开天辟地,在机器上开辟了一个虚拟的空间,然后才有了java生存的土壤。JVM也是中高级程序员,架构师,系统调优师等职位所必须要了解甚至深入掌握的知识点。当然,本系列的重点是内存及性能上的优化,所以本文只对JVM做一定概略性的讲解,不做太深入的研究。本文主要内容如下:

一、什么是JVM?

咱们这里借鉴百度百科的解释:

JVM是Java Virtual Machine 的缩写,即Java虚拟机,它是一种用于计算设备的规范,通过在实际的计算机上仿真模拟各种计算机功能来实现,可以简单理解为,它是一个在实际计算机中虚构出来的寄生计算机。Java源文件经过编译器编译成.class文件(字节码文件)后,由JVM来执行。JVM拥有一套支持java字节码文件(.class文件)执行的环境,可以将.class文件解释成具体平台上的机器指令并执行。Java程序只需要生成.class文件,即可以在任何装有JVM的设备上运行,而不需要理会具体操作系统平台相关的信息。此时的JVM就像一个翻译官一样连接连接着.class文件和系统平台。Java的这个特性叫做平台无关性,实现了“一次编译,到处运行”,JVM就是实现Java这个功能的大功臣。

二、JDK,JRE,JVM是什么关系?

如下截图为JDK安装包结构

1、JDK

Java Development Kit 的缩写,即 Java开发工具包,提供了开发java程序所需要的基本条件。在上图JDK安装包截图的红色边框中

  • bin:最主要包含了编辑器javac.exe,功能是将java源文件编译为.class文件。
  • include:包含了Java和JVM交互用的头文件。
  • lib:包含了java开发所需的类库。
  • jre:为Java运行环境。

2、JRE

Java Runtime Environment的缩写,即Java运行环境,下图为JRE文件夹的内容。注意,JRE是运行环境,而不是开发环境。

  • bin:可以理解为JVM,其中javaw.exe或java.exe用于执行.class文件。
  • lib:提供了JVM执行所需要的库。

3、JVM

执行.class文件。

4、结论

这三者的关系可以通过下图(摘自某网站)来理解:JDK包含了JRE,JRE又包含了JVM(对于比较懒得童鞋,可以先记住这个结论)。图中提到的Java开发工具,集成有类库和编译工具,只需关联jre即可。

三、JVM的工作

1、Java文件执行流程图

下图显示了JVM在java程序工作流中的位置,可以结合前面的内容来看。

2、JVM实际工作内容

实际上JVM的执行过程中,主要做了三个工作:

(1)加载并执行.class文件;

(2)管理并分配内存(推荐阅读:【朝花夕拾】Android性能篇之(二)Java内存分配);

(3)执行垃圾回收(推荐阅读:【朝花夕拾】Android性能篇之(三)Java内存回收)。

四、JVM生命周期

一个JVM实例对应一个独立运行的Java程序,是属于进程级别的,也有自己的生命周期:

1、启动

当启动一个Java程序的时候,就产生了一个JVM实例。我们还记得Java的入口函数 public static void main(String[] args)吗?每个拥有该函数的.class都可以作为JVM实例运行的起点。

2、运行

main()作为起点,启动主线程,其他任何线程都在该线程中启动。JVM有两种线程:User Thread(用户线程)和Daemon Thread(守护线程:为用户线程服务的线程),main()线程为用户线程,而守护线程通常由JVM自己使用。

3、消亡

当程序中的所有用户线程都终止时,JVM才会退出,守护线程无线程需要服务了,也就跟着退出了历史的舞台。若安全管理器允许,程序也可以使用Runtime或者System.exit()来退出。

五、JVM架构及工作原理

上图更详细地展示了JVM的架构,由图可知,JVM主要是划分为三个子系统 :(1)类加载器子系统 (2)运行时数据区 (3)执行引擎 和Java本地接口、本地方法库。

1、类加载子系统(Class Loader SubSystem)

Java的动态类加载功能由该子系统处理,当它在运行时(不是编译时)首次引用一个类时,它加载、链接并初始化该类文件(.class文件)。

(1)加载(Loading)

类的加载在此组件中完成,加载过程主要由下面三个加载器实现:

1)启动类加载器(BootStrap class Loader)。负责从启动类路径中加载类,无非就是rt.jar。这个加载器会被赋予最高优先级。

2)扩展类加载器(Extension class Loader)。负责加载ext目录(jre\lib)内的类。

3)应用程序类加载器(Application class Loader)。负责加载应用程序级别类路径,涉及到路径的环境变量等。

这三个类加载器会遵循委托层次算法(Delegation Hierarchy Algorithm)加载类文件。

(2)链接(Linking)

该过程主要完成以下三个步骤:

1)校验(Verify)。字节码校验器会校验生成的字节码是否正确,如果校验失败,我们会得到校验错误。

2)准备(Prepare)。分配内存并初始化默认值给所有的静态变量。

3)解析(Resolve)。所有符号内存引用被方法区(Method Area)的原始引用所替代。

(3)初始化(Initialization)

这是类加载的最后阶段,这里所有的静态变量会赋初始值,并且静态块将被执行。

2、运行时数据区(Runtime Data Area)

该部分将在后续的文章(【朝花夕拾】Android性能篇之(二)Java内存分配)中详细讲述,这里不做赘述。

3、执行引擎(Execution Engine)。

分配给运行时数据区的字节码将由执行引擎执行,执行引擎读取字节码并逐段执行。它包含了如下三个部分:解释器、编译器、垃圾回收器。

(1)解释器(interpreter)。

解释器能够快速地解释字节码,但执行却很慢。它的一个缺点就是,当一个方法被调用多次,每次都需要重新解释。

(2)JIT编译器。

JIT编译器消除了解释器的缺点,执行引擎利用解释器转换字节码,但如果是重复的代码,则使用JIT编译器将全部字节码编译成本机代码,本机代码将直接用于重复的方法调用,这样提高了系统的性能。它的工作由下面4个工具协同完成:

1)中间代码生成器。负责生成中间代码。

2)代码优化器。负责优化上面生成的中间代码。

3)目标代码生成器。负责生成机器代码或本机代码。

4)探测器(Profiler)。一个特殊的组件,负责寻找被多次调用的方法。

(3)垃圾回收器。

搜集并删除未引用的对象。可以通过调用“System.gc()”来触发垃圾回收,但并不保证会确实进行垃圾回收。JVM的垃圾回收只收集那些由new关键字创建的对象。所以,如果不是用new创建的对象,你可以使用finalize函数来执行清理。

4、Java本地接口(JNI,Native Method Interface)

JNI会与本地方法库进行交互并提供执行引擎所需的本地库。

5、本地方法库(Native Method Library)

它是一个执行引擎的本地库集合。

推荐阅读

       JVM工作原理和流程

深入理解JVM

JVM介绍

JVM_百度百科

最后推荐一本术,周志明著的《深入理解Java虚拟机——JVM高级特性与最佳实践》,业内评价很高,口碑非常好。

【朝花夕拾】Android性能篇之(一)序言及JVM的更多相关文章

  1. 【朝花夕拾】Android性能篇之(五)Android虚拟机

    前言 Android虚拟机的使用,使得android应用和Linux内核分离,这样做使得android系统更稳定可靠,比如程序中即使包含恶意代码,也不会直接影响系统文件:也提高了跨平台兼容性.在And ...

  2. 【朝花夕拾】Android性能篇之(六)Android进程管理机制

    前言        Android系统与其他操作系统有个很不一样的地方,就是其他操作系统尽可能移除不再活动的进程,从而尽可能保证多的内存空间,而Android系统却是反其道而行之,尽可能保留进程.An ...

  3. 【朝花夕拾】Android性能篇之(三)Java内存回收

    在上一篇日志([朝花夕拾]Android性能篇之(二)Java内存分配)中有讲到,JVM内存由程序计数器.虚拟机栈.本地方法栈.GC堆,方法区五个部分组成.其中GC堆是一块多线程的共享区域,它存在的作 ...

  4. 【朝花夕拾】Android性能篇之(七)Android跨进程通信篇

    前言 只要是面试高级工程师岗位,Android跨进程通信就是最受面试官青睐的知识点之一.Android系统的运行由大量相互独立的进程相互协助来完成的,所以Android进程间通信问题,是做好Andro ...

  5. 【朝花夕拾】Android性能篇之(四)Apk打包

    前言 APK,即Android Package,是将android程序和资源整合在一起,形成的一个.apk文件.相信所有的Android程序员是在IDE的帮助下,完成打包轻而易举,但对打包流程真正清楚 ...

  6. 【朝花夕拾】Android性能篇之(八)来自官网的自白

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10823372.html],谢谢! Android性能优化无疑是Android中的一个重点,也是 ...

  7. 【朝花夕拾】Android性能篇之(八)ANR篇--草稿

    1.ANR概念 2.ANR发生场景 Android开发者官网 上说到了两个原因:(1)点击按键或者触摸屏幕等输入事件在5s内没有响应:(2)10s内没有完成广播事件.如下所示: Android wil ...

  8. 【朝花夕拾】Android性能篇之(二)Java内存分配

    前言        在内存方面,相比于C/C++程序员,咱们java系程序员算是比较幸运的,因为对于内存的分配和回收,都交给了JVM来处理了,而不需要手动在代码中去完成.有了虚拟机内存管理机制,也就不 ...

  9. Android 性能篇 -- 带你领略Android内存泄漏的前世今生

    基础了解 什么是内存泄漏? 内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗.内存泄漏并不是指物理上的内存消失,这里的内存泄漏是指由程序分配的内存但是由于程序逻辑错误而导致程序失 ...

随机推荐

  1. Vagrant 安装以及private_network配置

    (需先安装virtuabox,vagrant) 1.下载centos 7 镜像,vagrant box add ceshi 镜像名 或者是使用先前vagrant package出来的box,进行加载镜 ...

  2. FunData — 电竞大数据系统架构演进

    电竞出现在人们视野中的频率越来越高了,此次选取FunData作为电竞数据平台,v1.0 beta版本主要提供由Valve公司出品的顶级MOBA类游戏DOTA2相关数据接口(详情:open.varena ...

  3. Loading Data into a Table;MySQL从本地向数据库导入数据

    在localhost中准备好了一个test数据库和一个pet表: mysql> SHOW DATABASES; +--------------------+ | Database | +---- ...

  4. 图形上下文导论(Introduction to SWT Graphics)zz

    图形上下文导论(Introduction to SWT Graphics) 摘要: org.eclipse.swt.graphics包(package),包含了管理图形资源的类.只要实现了org.ec ...

  5. 使用GitHub作为Maven仓库并引用

    网上太多的博客都是那些傻逼抄袭,然后直接复制粘贴然后就成为自己的博客了,这种人,真的很欠揍,我在网上查了一个下午的资料,终于找到一个写得非常详细的兄弟 链接如下:https://blog.csdn.n ...

  6. layedit第三次改造

    原文链接:http://www.bianbingdang.com/article_detail/105.html 作为技术人员,在网上写代码,常常涉及代码块的编写.一个好的代码块,让页面美化很多. 由 ...

  7. Hive与Hbase整合

    Hive与Hbase整合 1.文档 Hive HBase Integration 2.拷贝jar文件 2.1.把Hbase的lib目录下面的jar文件全部拷贝到Hive的lib目录下面 cd /hom ...

  8. AES加密算法详解

    AES 是一个对称密码分组算法,分组长度为128bit,密钥长度为128.192 和 256 bit. 整个加密过程如下图所示. 1.密钥生成算法 密钥扩展过程: 1)  将种子密钥按下图所示的格式排 ...

  9. sublime设置sublimeREPL-python-run current file 快捷键

    弄了3个小时的快捷键,一直不能成功使用,百度上一堆一样的方法,最后FQ才找到能用的方法,真是服了. 方法: ①首选项->快捷键设置 填写如下内容: [ {"keys": [& ...

  10. spring-cloud-Zuul学习(四)【中级】--自定义zuul Filter详解【重新定义spring cloud实践】

      实现自定义zuul Filter 方法很简单,只要继承ZuulFilter跟加入到spring IOC容器即可,zuulFilter是一个抽象类,里面包含以下方法需要我们实现: String fi ...