解释器原理,揭秘Java虚拟机:JVM设计原理与实现详细资料大全
解释器原理,揭秘Java虚拟机:JVM设计原理与实现详细资料大全详细介绍
本文目录一览: Python解释器是什么?Python解释器的两种形式说明
Python是一门开源免费、通用型的脚本编程语言,它上手简单,功能强大,它也是互联网最热门的编程语言之一。不管是传统的Web开发、PC软件开发、Linux运维,还是大数据分析、机器学习、人工智能,Python都能胜任。对于准备自学或者想要提升Python的小伙伴来说,可能找到一套合适的课程学习往往能够事半功倍!为大家提供到了四套潮享教育金牌讲师李老师的Python入门到精通视频课程,感兴趣就可以点击了解~
Python解释器是什么?
1)交互模式
交互模式指的是我们在终端进入Python或者在IDLE中输入一行代码执行一次的模式,在后面的学习中,部分例题会采用交互模式。
以我们刚装载好的IDLE为例来介绍一下交互模式,首先我们找到我们的Python解释器,在当前页面可以直接进行交互。
注:以交互模式运行时通常被称为Pythonshell
我们可以看到‘>>>’这个符号,我们可以在他后面进行输入指令,首先我们来输入一条简单的指令看一下效果。
第一行为我们输入的信息,回车(enter)之后会看到第二行的信息,也就是解释器打印出的内容。(我们在一次交互模式下定义过的变量等都是可以重复使用的)
然后‘>>>’再次出现等待我们的第二次指令的发送。
下面再展示几个实例,此时你也可以打开你的解释器进行练习。
在交互模式下如果出现错误代码系统会立刻报错。
交互模式在我们学习新内容的时候可以得到及时的调试并得到反馈。
2)文件模式
尽管交互模式在调试的时候使用着很方便,但却不利于保存,它只是简单的执行并显示在屏幕上,我们在需要编写之后并保存下来就要采用文件模式。
我们可以创建一个文本文件并以.py结尾然后使用IDLE打开,或者在IDLE中直接点击File->NewFile进入一个文件,然后可以进行代码的编写。
先编写一段入门代码:
通过F5或者在Run中runModule执行文件。
运行结果如下:
3)文件模式下进行交互
文件模式下是先编写程序然后运行到shell页面
然后我们运行它来进行交互
在交互的过程中,如果我们的主程序,也就是test.py是没有错误的,就可
以在交互页面一直进行操作,哪怕是语法错误也仍在当前文件下。但是如果我们主程序(test.py)出现了语法错误,那么出现错误的语句下面的语句都不会被执行。
我们来看个例子:
代码如下:
我们来研究分析一下当中间有一步为错误之后,后续语句是否会被处理。
以上就是关于“Python解释器是什么?Python解释器的两种形式说明”的全部内容分享了,希望小兔的精彩解答对你的Python编程学习有一定的帮助!Python计算机语言看起来很专业很难学,但是只要掌握原理逻辑,就能够逐步掌握攻破!想自学Python的小伙伴,小手点击此链接:
python解释器是什么
我们怎么让计算机去读取并执行Python代码文件呢?python解释器是什么?Python语言是编程语言,是计算机能听懂的语言。计算机的大脑是CPU, 中文名叫中央处理器,它仍然不能直接处理 Python 语言。CPU 只能直接处理机器指令语言,那是一种由0和1 数字组成的语言,像下面这样,这是一种我们人很难直接写出来的语言。所以,我们需要一个翻译, 把Python语言翻译成 计算机CPU 能听懂的 机器指令语言,这样计算机才能按照我们的Python程序的要求去做事。就像如果你要让一个美国人干一件事,你又只会说中国话,那么你就需要一名会说英语的中国翻译, 你和翻译说中国话,翻译听了,再对美国人说英语,告诉他怎么做。让计算机执行Python程序时,这个翻译就是 Python解释器。Python解释器本身也是个程序, 它是解释执行 Python代码的,所以叫解释器。没有它,我们的Python代码是没有办法运行的。我们运行Python程序时,先运行Python解释器,通过这个解释器,去读取我们的Python程序文件,这个解释器再以机器指令语言告诉CPU如何去做。其原理如下图所示:所以说要运行Python程序,必须要有 Python解释器。
ue5python原理
Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后解释器一条一条执行字节码指令,从而完成程序的执行。
1.1python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后解释器会从编译得到的PyCodeObject对象中一条一条执行字节码指令,
并在当前的上下文环境中执行这条字节码指令,从而完成程序的执行。Python解释器实际上是在模拟操作中执行文件的过程。PyCodeObject对象
中包含了字节码指令以及程序的所有静态信息,但没有包含程序运行时的动态信息——执行环境(PyFrameObject)
2. 字节码
字节码在python解释器程序里对应的是PyCodeObject对象
.pyc文件是字节码在磁盘上的表现形式
2.1从整体上看:OS中执行程序离不开两个概念:进程和线程。python中模拟了这两个概念,模拟进程和线程的分别是PyInterpreterState和
PyTreadState。即:每个PyThreadState都对应着一个帧栈,python解释器在多个线程上切换。当python解释器开始执行时,它会先进行一
些初始化操作,最后进入PyEval_EvalFramEx函数,它的作用是不断读取编译好的字节码,并一条一条执行,类似CPU执行指令的过程。函数内部
主要是一个switch结构,根据字节码的不同执行不同的代码。
3. .pyc文件
PyCodeObject对象的创建时机是模块加载的时候,及import
Python test.py会对test.py进行编译成字节码并解释执行,但是不会生成test.pyc
如果test.py加载了其他模块,如import urlib2, Python会对urlib2.py进行编译成字节码,生成urlib2.pyc,然后对字节码进行解释
如果想生成test.pyc,我们可以使用Python内置模块py_compile来编译。
加载模块时,如果同时存在.py和pyc,Python会尝试使用.pyc,如果.pyc的编译时间早于.py的修改时间,则重新编译.py并更新.pyc。
4. PyCodeObject
Python代码的编译结果就是PyCodeObject对象
typedef struct {
PyObject_HEAD
int co_argcount; /* 位置参数个数 */
int co_nlocals; /* 局部变量个数 */
int co_stacksize; /* 栈大小 */
int co_flags;
PyObject *co_code; /* 字节码指令序列 */
PyObject *co_consts; /* 所有常量集合 */
PyObject *co_names; /* 所有符号名称集合 */
PyObject *co_varnames; /* 局部变量名称集合 */
PyObject *co_freevars; /* 闭包用的的变量名集合 */
PyObject *co_cellvars; /* 内部嵌套函数引用的变量名集合 */
/* The rest doesn’t count for hash/cmp */
PyObject *co_filename; /* 代码所在文件名 */
PyObject *co_name; /* 模块名|函数名|类名 */
int co_firstlineno; /* 代码块在文件中的起始行号 */
PyObject *co_lnotab; /* 字节码指令和行号的对应关系 */
void *co_zombieframe; /* for optimization only (see frameobject.c) */
} PyCodeObject;
5. .pyc文件格式
加载模块时,模块对应的PyCodeObject对象被写入.pyc文件
6.分析字节码
6.1解析PyCodeObject
Python提供了内置函数compile可以编译python代码和查看PyCodeObject对象
6.2指令序列co_code的格式
opcode oparg opcode opcode oparg …
1 byte 2 bytes 1 byte 1 byte 2 bytes
Python内置的dis模块可以解析co_code
7. 执行字节码
Python解释器的原理就是模拟可执行程序再X86机器上的运行,X86的运行时栈帧如下图
Python解释器的原理就是模拟上述行为。当发生函数调用时,创建新的栈帧,对应Python的实现就是PyFrameObject对象。
PyFrameObject对象创建程序运行时的动态信息,即执行环境
7.1 PyFrameObject
typedef struct _frame{
PyObject_VAR_HEAD //"运行时栈"的大小是不确定的
struct _frame *f_back; //执行环境链上的前一个frame,很多个PyFrameObject连接起来形成执行环境链表
PyCodeObject *f_code; //PyCodeObject 对象,这个frame就是这个PyCodeObject对象的上下文环境
PyObject *f_builtins; //builtin名字空间
PyObject *f_globals; //global名字空间
PyObject *f_locals; //local名字空间
PyObject **f_valuestack; //"运行时栈"的栈底位置
PyObject **f_stacktop; //"运行时栈"的栈顶位置
//...
int f_lasti; //上一条字节码指令在f_code中的偏移位置
int f_lineno; //当前字节码对应的源代码行
//...
//动态内存,维护(局部变量+cell对象集合+free对象集合+运行时栈)所需要的空间
PyObject *f_localsplus[1];
} PyFrameObject;
每一个 PyFrameObject对象都维护了一个 PyCodeObject对象,这表明每一个 PyFrameObject中的动态内存空间对象都和源代码中的一段Code相对应。
简述shell的工作原理
Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言的统称。
shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。
shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用。用户在提示符下输入的命令都由shell先解释然后传给Linux核心。
有一些命令,比如改变工作目录命令cd,是包含在shell内部的。还有一些命令,例如拷贝命令cp和移动命令rm,是存在于文件系统中某个目录下的单独的程序。对用户而言,不必关心一个命令是建立在shell内部还是一个单独的程序。
shell首先检查命令是否是内部命令,若不是再检查是否是一个应用程序(这里的应用程序可以是Linux本身的实用程序,如ls和rm,也可以是购买的商业程序,如xv,或者是自由软件,如emacs)。然后shell在搜索路径里寻找这些应用程序(搜索路径就是一个能找到可执行程序的目录列表)。如果键入的命令不是一个内部命令并且在路径里没有找到这个可执行文件,将会显示一条错误信息。如果能够成功找到命令,该内部命令或应用程序将被分解为系统调用并传给Linux内核。
深入探索Java工作原理:JVM,内存回收及其他
Java语言引入了Java虚拟机 具有跨平台运行的功能 能够很好地适应各种Web应用 同时 为了提高Java语言的性能和健壮性 还引入了如垃圾回收机制等新功能 通过这些改进让Java具有其独特的工作原理
.Java虚拟机
Java虚拟机(Java Virtual Machine JVM)是软件模拟的计算机 它可以在任何处理器上(无论是在计算机中还是在其他电子设备中)安全兼容地执行保存在 class文件中的字节码 Java虚拟机的 机器码 保存在 class文件中 有时也可以称之为字节码文件
Java程序的跨平台特性主要是指字节码文件可以在任何具有Java虚拟机的计算机或者电子设备上运行 Java虚拟机中的Java解释器负责将字节码文件解释成为特定的机器码进行运行 因此在运行时 Java源程序需要通过编译器编译成为 class文件
Java虚拟机的建立需要针对不同的软硬件平台来实现 既要考虑处理器的型号 也要考虑操作系统的种类 由此在SPARC结构 X 结构 MIPS和PPC等嵌入式处理芯片上 在UNIX Linux Windows和部分实时操作系统上都可实现Java虚拟机
.无用内存自动回收机制
在程序的执行过程中 部分内存在使用过后就处于废弃状态 如果不及时进行回收 很有可能会导致内存泄漏 进而引发系统崩溃 在C++语言中是由程序员进行内存回收的 程序员需要在编写程序时把不再使用的对象内存释放掉 这种人为管理内存释放的方法往往由于程序员的疏忽而致使内存无法回收 同时也增加了程序员的工作量 而在Java运行环境中 始终存在着一个系统级的线程 专门跟踪内存的使用情况 定期检测出不再使用的内存 并自动进行回收 避免了内存的泄露 也减轻了程序员的工作量
.代码安全性检查机制
安全和方便总是相对矛盾的 Java编程语言的出现使得客户端计算机可以方便地从网络上上传或下载Java程序到本地计算机上运行 但是如何保证该Java程序不携带病毒或者没有其他危险目的呢?为了确保Java程序执行的安全性 Java语言通过Applet程序来控制非法程序的安全性 也就是有了它才确保Java语言的生存
Java字节码的执行需要经过以下 个步骤
( )由类装载器(class loader)负责把类文件( class文件)加载到Java虚拟机中 在此过程需要检验该类文件是否符合类文件规范
( )字节码校验器(bytecode verifier)检查该类文件的代码中是否存在着某些非法操作 例如Applet程序中写本地计算机文件系统的操作
( )如果字节码校验器检验通过 由Java解释器负责把该类文件解释成为机器码进行执行
注意
Java虚拟机采用 沙箱 运行模式 即把Java程序的代码和数据都限制在一定内存空间里执行 不允许程序访问该内存空间以外的内存 如果是Applet程序 还不允许访问客户端机器的文件系统
Java的运行环境
无论哪种语言都需要有它特定的运行环境 也就是平台 Java语言同样不例外 但是如何理解Java程序与硬件环境无关呢?
几乎所有的语言都需要通过编译或者解释才可以被计算机执行 但是Java有一点不同 它同时需要这两个过程 其实 也正是因为这个原因才使Java这种语言具有了平台无关性 当完成一个Java源程序后 首先 通过Java翻译程序将它编译成一种叫做字节码的中间代码 然后再由Java平台的解释器将它转换成为机器语言来执行 这一平台的核心就是JVM
Java的编译过程与其他的语言不同 像C++这样的语言 在编译时它是与计算机的硬件平台信息密不可分的 编译程序通过查表将所有指令的操作数和操作码等转换成内存的偏移量 即程序运行时的内存分配方式 目的是保证程序正常运行 而Java却是将指令转换成为一种 class的文件 这种文件不包含硬件的信息 需要执行时只要经过安装有JVM的机器进行解释 创建内存分配后再通过查表来确定一条指令所在的地址 这样就有效地保证了Java的可移植性和安全性
Java平台具有这样的特性和它的结构有关 通常一个程序运行的平台是一个硬件或者软件运行的环境 目前比较流行的是Windows XP Linux Solaris和MacOS Java的平台不太一样 它由两个部分组成 即JVM和应用程序设计接口
.JVM
JVM是Java平台的核心 为了让编译产生的字节码能更好地解释与执行 因此把JVM分成了 个部分 JVM解释器 指令系统 寄存器 栈 存储区和碎片回收区
◆JVM解释器 即这个虚拟机处理字段码的CPU
◆JVM指令系统 该系统与计算机很相似 一条指令由操作码和操作数两部分组成 操作码为 位二进制数 主要是为了说明一条指令的功能 操作数可以根据需要而定 JVM有多达 种不同的操作指令
◆寄存器 JVM有自己的虚拟寄存器 这样就可以快速地与JVM的解释器进行数据交换 为了功能的需要 JVM设置了 个常用的 位寄存器 pc(程序计数器) optop(操作数栈顶指针) frame(当前执行环境指针)和vars(指向当前执行环境中第一个局部变量的指针)
◆JVM栈 指令执行时数据和信息存储的场所和控制中心 它提供给JVM解释器运算所需要的信息
◆存储区 JVM存储区用于存储编译过后的字节码等信息
◆碎片回收区 JVM碎片回收是指将使用过的Java类的具体实例从内存进行回收 这就使得开发人员免去了自己编程控制内存的麻烦和危险 随着JVM的不断升级 其碎片回收的技术和算法也更加合理 JVM 版后产生了一种叫分代收集技术 简单来说就是利用对象在程序中生存的时间划分成代 以此为标准进行碎片回收
.Java应用程序设计接口
Java Application Programming Interface简称Java API 其中文名为Java应用程序设计接口 它是一个软件集合 其中有许多开发时所需要的控件 可以用它来辅助开发
lishixinzhi/Article/program/Java/hx/201311/26733
lua 与 c++或者c 交互的底层原理谁能解释一下?最最底层的,为什么它们调用C或者C++的函数?
在你的脚本开头写上 require 'mydll',就可以调用了。看看error是什么,根据信息去调错。
lua编译器也就是解释器,所谓脚本就是加载时编译嘛!
另:调试脚本的方法就是靠log来分析了。lua调用函数当然用文本,要不怎么调。
直接看源码。。。代码在loadlib.c和lapi.c里
因为 lua 解释器就是用 C 语言开发的,而目前 C 语言在协议上与 C++ 是相同的(或者说使用同一套C协议,虽然C++由C衍生,但对于编译器而言反而更像是从C++删减成C,所以C与C++兼容)
揭秘Java虚拟机:JVM设计原理与实现详细资料大全
《揭秘Java虚拟机:JVM设计原理与实现》是2017年电子工业出版社出版的图书,作者是封亚飞。
基本介绍 书名 :揭秘Java虚拟机:JVM设计原理与实现 作者 :封亚飞 ISBN :9787121315411 页数 :700 出版时间 :2017-06 开本 :16开 千 字 数 :942 内容简介,目录, 内容简介 《揭秘Java虚拟机:JVM设计原理与实现》从源码角度解读HotSpot的内部实现机制,本书主要包含三大部分——JVM数据结构设计与实现、执行引擎机制及记忆体分配模型。 数据结构部分包括Java位元组码档案格式、常量池解析、栏位解析、方法解析。每一部分都给出详细的源码实现分析,例如栏位解析一章,从源码层面详细分析了Java栏位重排、栏位继承等关键机制。再如方法解析一章,给出了Java多态特性在源码层面的实现方式。《揭秘Java虚拟机:JVM设计原理与实现》通过直接对原始码的分析,从根本上梳理和澄清Java领域中的关键概念和机制。 执行引擎部分包括Java方法调用机制、栈帧创建机制、指令集架构与解释器实现机制。这一话题是《揭秘Java虚拟机:JVM设计原理与实现》技术含量高的部分,需要读者具备一定的汇编基础。不过千万不要被“汇编”这个词给吓著,其实在作者看来,汇编相比于高级语言而言,语法非常简单,语义也十分清晰。执行引擎部分重点描述Java原始码如何转换为位元组码,又如何从位元组码转换为机器指令从而能够被物理CPU所执行的技术实现。同时详细分析了Java函式堆叠的创建全过程,在源码分析的过程中,带领读者从本质上理解到底什么是Java函式堆叠和栈帧,以及栈帧内部的详细结构。 记忆体分配部分主要包括类型创建与载入、对象实例创建与记忆体分配,例如new关键字的工作机制,import关键字的作用,再如java.lang.ClassLoader.loadClass()接口的本地实现机制。 《揭秘Java虚拟机:JVM设计原理与实现》并不是简单地分析源码实现,而是在描述HotSpot内部实现机制的同时,分析了HotSpot如此这般实现的技术必然性。读者在阅读《揭秘Java虚拟机:JVM设计原理与实现》的过程中,将会在很多地方看到作者本人的这种思考。 目录 第1章 Java虚拟机概述 1 1.1 从机器语言到Java——詹爷,你好 1 1.2 兼容的选择:一场生产力的革命 6 1.3 中间语言翻译 10 1.3.1 从中间语言翻译到机器码 11 1.3.2 通过C程式翻译 11 1.3.3 直接翻译为机器码 13 1.3.4 本地编译 16 1.4 神奇的指令 18 1.4.1 常见汇编指令 20 1.4.2 JVM指令 21 1.5 本章总结 24 第2章 Java执行引擎工作原理:方法调用 25 2.1 方法调用 26 2.1.1 真实的机器调用 26 2.1.2 C语言函式调用 41 2.2 JVM的函式调用机制 47 2.3 函式指针 53 2.4 CallStub函式指针定义 60 2.5 _call_stub_entry例程 72 2.6 本章总结 115 第3章 Java数据结构与面向对象 117 3.1 从Java算法到数据结构 118 3.2 数据类型简史 122 3.3 Java数据结构之偶然性 129 3.4 Java类型识别 132 3.4.1 class位元组码概述 133 3.4.2 魔数与JVM内部的int类型 136 3.4.3 常量池与JVM内部对象模型 137 3.5 大端与小端 143 3.5.1 大端和小端的概念 146 3.5.2 大小端产生的本质原因 148 3.5.3 大小端验证 149 3.5.4 大端和小端产生的场景 151 3.5.5 如何解决位元组序反转 154 3.5.6 大小端问题的避免 156 3.5.7 JVM对位元组码档案的大小端处理 156 3.6 本章总结 159 第4章 Java位元组码实战 161 4.1 位元组码格式初探 161 4.1.1 准备测试用例 162 4.1.2 使用javap命令分析位元组码档案 162 4.1.3 查看位元组码二进制 165 4.2 魔数与版本 166 4.2.1 魔数 168 4.2.2 版本号 168 4.3 常量池 169 4.3.1 常量池的基本结构 169 4.3.2 JVM所定义的11种常量 170 4.3.3 常量池元素的复合结构 170 4.3.4 常量池的结束位置 172 4.3.5 常量池元素总数量 172 4.3.6 第一个常量池元素 173 4.3.7 第二个常量池元素 174 4.3.8 父类常量 174 4.3.9 变数型常量池元素 175 4.4 访问标识与继承信息 177 4.4.1 aess_flags 177 4.4.2 this_class 178 4.4.3 super_class 179 4.4.4 interface 179 4.5 栏位信息 180 4.5.1 fields_count 180 4.5.2 field_info fields[fields_count] 181 4.6 方法信息 185 4.6.1 methods_count 185 4.6.2 method_info methods[methods_count] 185 4.7 本章回顾 205 第5章 常量池解析 206 5.1 常量池记忆体分配 208 5.1.1 常量池记忆体分配总体链路 209 5.1.2 记忆体分配 215 5.1.3 初始化记忆体 223 5.2 oop-klass模型 224 5.2.1 两模型三维度 225 5.2.2 体系总览 227 5.2.3 oop体系 229 5.2.4 klass体系 231 5.2.5 handle体系 234 5.2.6 oop、klass、handle的相互转换 239 5.3 常量池klass模型(1) 244 5.3.1 klassKlass实例构建总链路 246 5.3.2 为klassOop申请记忆体 249 5.3.3 klassOop记忆体清零 253 5.3.4 初始化mark 253 5.3.5 初始化klassOop._metadata 258 5.3.6 初始化klass 259 5.3.7 自指 260 5.4 常量池klass模型(2) 261 5.4.1 constantPoolKlass模型构建 261 5.4.2 constantPoolOop与klass 264 5.4.3 klassKlass终结符 267 5.5 常量池解析 267 5.5.1 constantPoolOop域初始化 268 5.5.2 初始化tag 269 5.5.3 解析常量池元素 271 5.6 本章总结 279 第6章 类变数解析 280 6.1 类变数解析 281 6.2 偏移量 285 6.2.1 静态变数偏移量 285 6.2.2 非静态变数偏移量 287 6.2.3 Java栏位记忆体分配总结 312 6.3 从源码看栏位继承 319 6.3.1 栏位重排与补白 319 6.3.2 private栏位可被继承吗 325 6.3.3 使用HSDB验证栏位分配与继承 329 6.3.4 引用类型变数记忆体分配 338 6.4 本章总结 342 第7章 Java栈帧 344 7.1 entry_point例程生成 345 7.2 局部变数表创建 352 7.2.1 constMethod的记忆体布局 352 7.2.2 局部变数表空间计算 356 7.2.3 初始化局部变数区 359 7.3 堆叠与栈帧 368 7.3.1 栈帧是什么 368 7.3.2 硬体对堆叠的支持 387 7.3.3 栈帧开辟与回收 390 7.3.4 堆叠大小与多执行绪 391 7.4 JVM的栈帧 396 7.4.1 JVM栈帧与大小确定 396 7.4.2 栈帧创建 399 7.4.3 局部变数表 421 7.5 栈帧深度与slot复用 433 7.6 最大运算元栈与运算元栈复用 436 7.7 本章总结 439 第8章 类方法解析 440 8.1 方法签名解析与校验 445 8.2 方法属性解析 447 8.2.1 code属性解析 447 8.2.2 LVT&LVTT 449 8.3 创建methodOop 455 8.4 Java方法属性复制 459 8.5 与 461 8.6 查看运行时位元组码指令 482 8.7 vtable 489 8.7.1 多态 489 8.7.2 C++中的多态与vtable 491 8.7.3 Java中的多态实现机制 493 8.7.4 vtable与invokevirtual指令 500 8.7.5 HSDB查看运行时vtable 502 8.7.6 miranda方法 505 8.7.7 vtable特点总结 508 8.7.8 vtable机制逻辑验证 509 8.8 本章总结 511 第9章 执行引擎 513 9.1 执行引擎概述 514 9.2 取指 516 9.2.1 指令长度 519 9.2.2 JVM的两级取指机制 527 9.2.3 取指指令放在哪 532 9.2.4 程式计数器在哪里 534 9.3 解码 535 9.3.1 模板表 535 9.3.2 汇编器 540 9.3.3 汇编 549 9.4 栈顶快取 558 9.5 栈式指令集 565 9.6 运算元栈在哪里 576 9.7 栈帧重叠 581 9.8 entry_point例程机器指令 586 9.9 执行引擎实战 588 9.9.1 一个简单的例子 588 9.9.2 位元组码运行过程分析 590 9.10 位元组码指令实现 597 9.10.1 iconst_3 598 9.10.2 istore_0 599 9.10.3 iadd 600 9.11 本章总结 601 第10章 类的生命周期 602 10.1 类的生命周期概述 602 10.2 类载入 605 10.2.1 类载入——镜像类与静态栏位 611 10.2.2 Java主类载入机制 617 10.2.3 类载入器的载入机制 622 10.2.4 反射载入机制 623 10.2.5 import与new指令 624 10.3 类的初始化 625 10.4 类载入器 628 10.4.1 类载入器的定义 628 10.4.2 系统类载入器与扩展类载入器创建 634 10.4.3 双亲委派机制与破坏 636 10.4.4 预载入 638 10.4.5 引导类载入 640 10.4.6 载入、连结与延迟载入 641 10.4.7 父载入器 645 10.4.8 载入器与类型转换 648 10.5 类实例分配 649 10.5.1 栈上分配与逃逸分析 652 10.5.2 TLAB 655 10.5.3 指针碰撞与eden区分配 657 10.5.4 清零 658 10.5.5 偏向锁 658 10.5.6 压栈与取指 659 10.6 本章总结 661
java虚拟机工作原理?
Java虚拟机处于机器和编译程序之间,在任何平台上都提供给编译程序一个共同的接口。Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行。 Java虚拟机的主要任务是装载class文件并且执行其中的字节码。Java虚拟机包含一个类装载器,它可以从程序和API中装载class文件。字节码由执行引擎来执行。 Java虚拟机结构 类装载器的体系结构是Java虚拟机在安全性和网络移动性上发挥重要作用的一个方面,图中所示的类装载器可以包含多个类装载器的子系统, Java应用程序能够在运行时决定需要安装的类,并且将被不同的类装载器装载的类存放在不同的命名空间。 执行引擎处于Java虚拟机的核心位置,它的行为由指令集所决定,其主要作用就是解释字节码(即运行经过编译后的Java程序的class文件) ,不同的执行引擎实现可能非常不同。由软件实现的虚拟机的执行引擎分为一次性解释字节码、即时编译器和自适应优化器,由硬件芯片构成的虚拟机用本地方法执行Java字节码,它的执行引擎是内嵌在芯片里。 Java虚拟机相当于一个堆栈计算机,它在指令间传送信息时不使用任何物理寄存器,而使用堆栈的帧来表示方法的状态、字节码的操作对象、方法的参数空间及局部变量的空间,它的“程序计数器”为一个伪寄存器,是当前所执行指令的字节码数组的一个指针。 Java实现方法 Java有两种实现方法:Java方法和本地方法。Java方法是由Java 语言编写,编译成字节码,存储在class文件中。本地方法是由其他语言(比如C,C++,或者汇编语言)编写的,编译成和处理器相关的机器代码,保存在动态连接库中,格式是各个平台专有的,它是联系Java程序和底层主机操作系统的连接方法。Java方法与平台无关,但是本地方法却不是,运行中的 Java程序调用本地方法时,虚拟机装载包含这个本地方法的动态库,并调用这个方法。通过本地方法, Java程序可以直接访问底层操作系统的资源,使程序和特定的平台相关,一个本地方法接口——Java本地接口(JNI)使得本地方法可以在特定的主机系统的任何一个Java平台上运行。
从宏观上介绍一下Java虚拟机的工作原理。从最初编写的Java源文件(.java文件)是如何一步步执行的,如下图所示,首先Java源文件经过前端编译器(javac或ECJ)将.java文件编译为Java字节码文件,然后JRE加载Java字节码文件,载入系统分配给JVM的内存区,然后执行引擎解释或编译类文件,再由即时编译器将字节码转化为机器码。主要介绍下图中的类加载器和运行时数据区两个部分。
(1)类加载指将类的字节码文件(.class)中的二进制数据读入内存,将其放在运行时数据区的方法区内,然后在堆上创建java.lang.Class对象,封装类在方法区内的数据结构。类加载的最终产品是位于堆中的类对象,类对象封装了类在方法区内的数据结构,并且向JAVA程序提供了访问方法区内数据结构的接口。如下是类加载器的层次关系图。
启动类加载器(BootstrapClassLoader):在JVM运行时被创建,负责加载存放在JDK安装目录下的jre\lib的类文件,或者被-Xbootclasspath参数指定的路径中,并且能被虚拟机识别的类库(如rt.jar,所有的java.*开头的类均被Bootstrap ClassLoader加载)。启动类无法被JAVA程序直接引用。
扩展类加载器(Extension ClassLoader):该类加载器负责加载JDK安装目录下的\jre\lib\ext的类,或者由java.ext.dirs系统变量指定路径中的所有类库,开发者也可以直接使用扩展类加载器。
应用程序类加载器(AppClassLoader):负责加载用户类路径(Classpath)所指定的类,开发者可以直接使用该类加载器,如果应用程序中没有定义过自己的类加载器,该类加载器为默认的类加载器。
用户自定义类加载器(User ClassLoader):JVM自带的类加载器是从本地文件系统加载标准的java class文件,而自定义的类加载器可以做到在执行非置信代码之前,自动验证数字签名,动态地创建符合用户特定需要的定制化构建类,从特定的场所(数据库、网络中)取得java class。
注意如上的类加载器并不是通过继承的方式实现的,而是通过组合的方式实现的。而JAVA虚拟机的加载模式是一种委派模式,如上图中的1-7步所示。下层的加载器能够看到上层加载器中的类,反之则不行。类加载器可以加载类但是不能卸载类。说了一大堆,还是感觉需要拿点代码说事。
首先先定义自己的类加载器MyClassLoader,继承自ClassLoader,并覆盖了父类的findClass(String name)方法,如下:
利用定义的类加载器加载指定的字节码文件,如通过MyClassLoader加载C:\\Users\\Administrator\\下的Test.class字节码文件,代码如下所示:
(2)运行时数据区
字节码的加载第一步,其后分别是认证、准备、解析、初始化,那么这些步骤又具体做了哪些工作,如下图所示:
(3)如下将介绍运行时数据区,主要分为方法区、Java堆、虚拟机栈、本地方法栈、程序计数器。其中方法区和Java堆一样,是各个线程共享的内存区域,而虚拟机栈、本地方法栈、程序计数器是线程私有的内存区。
Java堆:Java堆是Java虚拟机所管理的内存中最大的一块,被进程的所有线程共享,在虚拟机启动时被创建。该区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,随着JIT编译器的发展与逃逸分支技术逐渐成熟,栈上分配、标量替换等优化技术使得对象在堆上的分配内存变得不是那么“绝对”。Java堆是垃圾收集器管理的主要区域。由于现在的收集器基本都采用分代收集算法,所以Java堆中还可以分为老年代和新生代(Eden、From Survivor、To Survivor)。根据Java虚拟机规范,Java堆可以处于物理上不连续的内存空间,只要逻辑上连续即可。该区域的大小可以通过-Xmx和-Xms参数来扩展,如果堆中没有内存完成实例分配,并且堆也无法扩展,将会抛出OutOfMemoryError异常。
方法区:用于存储被Java虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。不同于Java堆的是,Java虚拟机规范对方法区的限制非常宽松,可以选择不实现垃圾收集。但并非数据进入了方法区就“永久”存在了,这区域内存回收目标主要是针对常量池的回收和对类型的卸载。如果该区域内存不足也会抛出OutOfMemoryError异常。
常量池:这个名词可能大家也经常见,是方法区的一部分。Class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池,用于存放编译期生成的各种字面量和符号引用。Java虚拟机运行期间,也可能将新的常量放入常量池(如String类的intern()方法)。
虚拟机栈:线程私有,生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。如果请求的站深度大于虚拟机所允许的深度,将抛出StackOverflowError异常,虚拟机栈在动态扩展时如果无法申请到足够的内存,就会抛出OutOfMemoryError异常。
过最简单的一段代码解释一下,程序在运行时数据区个部分的变化情况。
(4)通过编译器将Test.java文件编译为Test.class,利用javap -verbose Test.class对编译后的字节码进行分析,如下图所示:
(5)看看运行时数据区的变化:
Web前端必学JavaScript引擎工作原理
JavaScript引擎是什么?
JavaScript引擎是一种用于将我们的代码转换为机器可读语言的引擎。如果没有JavaScript引擎,你编写的代码对计算机来说简直是一堆“胡言乱语”。不仅仅是JavaScript,其他所有编程语言都需要一个类似的引擎,来将这些“胡言乱语”转换成对计算机有意义的语言。简单地说,JavaScript解析引擎就是能够“读懂”JavaScript代码,并准确地给出代码运行结果的一段程序。比方说,当你写了 var a = 1 + 1; 这样一段代码,JavaScript引擎做的事情就是看懂(解析)你这段代码,并且将a的值变为2。
JavaScript引擎的组成部分有哪些?
1、编译器。主要工作是将源代码编译成抽象语法树,然后在某些引擎中还包含将抽象语法树转换成字节码。
2、解释器。在某些引擎中,解释器主要是接受字节码,解释执行这个字节码,然后也依赖来及回收机制等。
3、JIT工具。一个能够JIT的工具,将字节码或者抽象语法树转换成本地代码,当然它也需要依赖牢记垃圾回收器和分析工具(profiler)。它们负责垃圾回收和收集引擎中的信息,帮助改善引擎的性能和功效。
以上就是环球青藤小编关于JavaScript引擎工作原理的相关内容分享,希望对大家有所帮助,想要了解更多相关内容,欢迎关注本平台!