深入理解JVM
来源:互联网 发布:php 检验日期格式 编辑:程序博客网 时间:2024/06/05 04:52
本文转载自:http://www.qszxin.com/notes/53.html
前面两篇关于Java的文章简单介绍了Java、JRE、JVM之间的联系以及JVM的一些特点,我们都知道Java字节码运行在JRE(Java Runtime Environment)中,而JRE中最重要的就是Java Virtual Machine(JVM)了,JVM负责解释和执行Java字节码,从Java程序员的角度来看,我们并不需要了解JVM如何运行就可以写出很多漂亮的程序。
但是作为一名Java开发者,如果能够深入理解JVM的工作原理,可以帮助我们对Java这门语言有着更加深刻的认识,提高真实水平,也可以解决一些看上去摸不着头脑的bug,让程序更加具有效率。所以,这篇文章里,我将深入介绍JVM的工作原理,JVM的体系结构。
对于JVM的特点介绍请看我之前写的文章JVM初步了解,这里深入介绍JVM的结构,下图是Java程序的执行流程:
中间绿色部分就是JVM的结构,一个类加载器加载Java字节码到运行时数据区,执行引擎执行Java字节码,指令计数器指向当前应该执行的指令。
运行时数据区详细结构图如下:
从操作系统的角度来看,进程是资源分配的最小单位,而线程则是CPU管理、调度的最小单位,线程往往共享所属进程的内存资源,但是线程的运行也需要分配一些资源,比如计数器、栈。当Java程序在JVM运行时,JVM就会为该进程分配数据区,进程运行时,每创建一个线程,都会为线程分配计数器、JVM栈、本地方法栈。
单个线程的数据区:
l 程序计数器:线程启动的时候,计数器就会被创建,其记录当前需要执行的指令地址
l JVM栈:线程启动的时候,栈就会被创建,栈中存储的是栈帧(Stack Frame),这里的栈也就是我们数据结构讲的栈,可以进行Push和Pop操作栈帧。结构图如下:
当一个方法在JVM中执行时,栈帧被创建,并且存储到对应线程的JVM栈中,当方法执行完毕返回时,从该线程的JVM栈中移除。因为在编译时就可以确定局部变量和操作数的大小,所以栈帧的大小也是确定的。
局部变量数组:索引0存储的是该方法所属对象的引用,从索引1开始存储的是方法参数,方法参数后存储的是方法内的局部变量。
操作数栈:这是方法的实际工作区,每个方法都是在操作数栈和局部变脸数组交换数据。我的理解是可以参考x86指令集,x86指令集中会使用一些通用寄存器来暂存中间数据,但是正如上篇文章所讲的JVM特点,JVM不是基于寄存器的,而是基于栈的。
l 本地方法栈:本地方法所需要的栈空间,JVM借助于JNI(Java Native Interface)执行C/C++程序,所以专门为这些程序创建栈空间。我的理解是,毕竟JVM是架构在真实操作系统之上,比如Windows、Linux之上,JVM也需要使用操作系统提供的接口来实现功能。
多线程共享的数据区:
l 堆:存储数组和对象,因为这一部分是动态存储的,垃圾回收会定时对该存储区进行回收空间
l 方法区:包括运行时常量池,类结构信息和方法信息,静态变量,每个类的方法字节码。
l 运行时常量池:每个类或者接口编译后的.class文件中具有常量池表,当JVM装载类之后,就解析常量池表到运行时常量池,其中包括数字值,String值,和运行时解析的方法引用(method reference)和属性域引用(field reference)。
- 深入理解JVM
- 深入理解JVM
- 深入理解JVM
- 深入理解JVM---转载
- 深入理解JVM
- 深入理解JVM(重要)
- 深入理解JVM
- 深入理解JVM
- 深入理解jvm
- 深入理解JVM
- JVM 深入理解
- 深入理解JVM
- 深入理解JVM
- 深入理解 JVM
- 深入理解JVM
- 深入理解JVM
- 深入理解JVM内部结构
- 深入理解JVM
- Android利用Fragment实现Tab布局
- iscsi 挂载网络存储及存储访问
- Android Studio中导入Vitamio框架
- android基础之六——多媒体编程
- Android 5.0/5.1 HOOK技术探究
- 深入理解JVM
- hdoj 2080 夹角有多大II
- am335x嵌入式开发-bootloader启动流程
- Microsoft(R) Developer Studio 已停止工作 解决办法(1)
- oracle之约束解析
- 【机房合作】单例模式实战
- Java特性学习
- YII config main.php
- oracle之索引分析