虚拟机

2017-09-07  本文已影响2292人  小楠总

前言

本篇文章将会介绍Java虚拟机(JVM)的结构等基础知识、Dalvik(DVM)/ART虚拟机与JVM的比较。

JVM结构

JVM的整体结构

将以JVM为代表讲解,因为DVM以及ART都是基于JVM进行改造的。

JVM结构如下图:

JVM结构.png

相关描述:

下面从代码的编译到执行过程对这个结构进行详细分析。

一、编译流程

JVM字节码即class文件,通过javac命令生成class文件的详细过程如下:

编译流程.png

其中最核心的就是编译器对词法、语法的分析,如果能够写一个编译器,那么就可以创造一门语言了。

二、类加载器

接下来看一下JVM的类加载器(Android的类加载器跟原生的类加载器不一样,但是都大同小异):

类加载.png

如上图所示,不同的类加载器加载不同的字节码文件,其中:

类加载流程如下:

加载流程.png

具体过程如下:

  1. Loading:从class文件中获取类的信息,并且载入JVM内存
  2. Verifying:检查读入的结构是否符合JVM规范的描述
  3. Preparing:分配一个结构用来存储类的信息
  4. Resolving:把类的常量池中的所有符号引用改变为直接引用
  5. Initialzing:执行初始化程序,把静态变量初始化为指定的值,执行static块等等

三、JVM内存管理

回顾一下这个图,JVM的内存按照逻辑分为4大部分:

JVM结构.png
  1. Java栈:主要作用是存放Java方法执行的时候所有的数据,由栈帧组成,一个栈帧代表一个方法的执行。每个方法从调用到执行完成就对应一个栈帧在虚拟机中的入栈到出栈。栈帧的信息包括局部变量表、栈操作数、动态链接、方法出口。
  2. 本地方法栈:专门为native方法服务的,例如C、C++方法。
  3. 方法区:存储被虚拟机加载的类信息、常亮、静态变量、即时编译器编译后等数据。
  4. 堆区:所有通过new创建的对象的内存都在堆中分配。堆内存分为新生代和老生代,新生代存储的是刚创建的对象。当内存不足的时候,虚拟机就会通过一系列算法把新生代的对象移动到老生代。
Tips1:当方法栈的深度大于JVM最大深度的时候,就会栈溢出。例如写一个没有退出的递归就会导致栈溢出(StackOverflow)。
Tips2:当新生代、老生代都满了的话,就会导致内存溢出(OOM)。
Tips3:新、老生代的动态调整是服务端开发需要掌握的一门技术,比如做即时通信服务端,Message临时对象比较多,那么适当增加新生代,便于内存分配,加快对象的创建。做大型服务类程序,不需要频繁创建,就可以扩大老生代,达到对象常驻效果,保证服务稳定性。

四、垃圾回收

下面来讲解一下虚拟机的垃圾回收(GC)的知识。主要包括垃圾的确定与收集、垃圾的回收、垃圾回收的时机。垃圾回收主要针对堆内存。

垃圾收集算法有:

垃圾回收算法主要有:

三种算法的过程图解如下所示:

标记-清除算法.png
复制算法.png
标记-整理算法.png
Tips:三种算法是混合使用的,不同情况,例如对象数量不同,采用不用的算法,已达到最大的效率。

触发垃圾回收主要有:

Dalvik VM(DVM)

为了更加适合移动端,Android基于JVM创造了DVM:

ART

ART虚拟机是DVM的进化版本:

如果觉得我的文字对你有所帮助的话,欢迎关注我

的公众号,我致力于各种技术的分享(尤其是各种视频教程),畅聊各种工程师成长经验,并包括各种办公室外的思考:书籍推荐、高效学习方法、写作、投资理财、创业、商业、运营、产品、时间管理、改变习惯等:

image

我的群欢迎大家进来探讨各种技术与非技术的话题,有兴趣的朋友们加我私人微信huannan88,我拉你进群交(♂)流(♀)

上一篇 下一篇

猜你喜欢

热点阅读