zoukankan      html  css  js  c++  java
  • 【朝花夕拾】Android性能篇之(一)序言及JVM

    序言

           转载请声明,转自【https://www.cnblogs.com/andy-songwei/p/9739836.html】,谢谢!

           笔者从事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即可。                

           JDK、JRE、JVM三者的区别与联系 - 以德糊人 - ——挨踢民工 Playkid—— 

    三、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目录(jrelib)内的类。

            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高级特性与最佳实践》,业内评价很高,口碑非常好。

  • 相关阅读:
    Good Bye 2014 B. New Year Permutation(floyd )
    hdu 5147 Sequence II (树状数组 求逆序数)
    POJ 1696 Space Ant (极角排序)
    POJ 2398 Toy Storage (叉积判断点和线段的关系)
    hdu 2897 邂逅明下 (简单巴什博弈)
    poj 1410 Intersection (判断线段与矩形相交 判线段相交)
    HDU 3400 Line belt (三分嵌套)
    Codeforces Round #279 (Div. 2) C. Hacking Cypher (大数取余)
    Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings (容斥原理)
    hdu 1576 A/B (求逆元)
  • 原文地址:https://www.cnblogs.com/andy-songwei/p/9739836.html
Copyright © 2011-2022 走看看