请注意,我的问题是关于JVM解释器,而不是JIT编译器。JIT编译器将java字节码转换为本机代码。因此,这必须意味着JVM中的解释器不会将字节码转换为机器码。因此,问题是:从本质上讲,口译员做什么?如果有人能帮我用一个简单的字节码示例来回答这个问题,相当于1 1=2,即解释器在执行这个加法操作时做了什么?(我的隐含问题是,如果解释器不翻译为机器代码,那么哪个CPU执行添加操作,那么该操作是如何执行的?实际执行什么机器代码来支持该添加操作?)
表达式1 1
将编译为以下字节码:
iconst_1
iconst_1
add
(实际上,它只会编译到iconst\u 2,因为Java编译器执行常量折叠,但为了回答这个问题,我们忽略它。)
因此,为了确切了解解释器对这些指令所做的操作,我们应该查看其源代码。const\u 1和add的相关部分分别从第983行和第1221行开始,让我们看一下:
#define OPC_CONST_n(opcode, const_type, value) \
CASE(opcode): \
SET_STACK_ ## const_type(value, 0); \
UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
OPC_CONST_n(_iconst_m1, INT, -1);
OPC_CONST_n(_iconst_0, INT, 0);
OPC_CONST_n(_iconst_1, INT, 1);
// goes on for several other constants
//...
#define OPC_INT_BINARY(opcname, opname, test) \
CASE(_i##opcname): \
if (test && (STACK_INT(-1) == 0)) { \
VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \
"/ by zero", note_div0Check_trap); \
} \
SET_STACK_INT(VMint##opname(STACK_INT(-2), \
STACK_INT(-1)), \
-2); \
UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \
// and then the same thing for longs instead of ints
OPC_INT_BINARY(add, Add, 0);
// other operators
整个事情都在一个检查当前指令操作码的开关语句中。
如果我们扩展宏魔术,用一个极其简化的模板替换周围的代码,并做出一些简化的假设(例如堆栈仅由int组成),我们最终会得到如下结果:
enum OpCode {
_iconst_1, _iadd
};
// ...
int* stack = new int[calculate_maximum_stack_size()];
size_t top_of_stack = 0;
size_t program_counter = 0;
while(program_counter < program_size) {
switch(opcodes[program_counter]) {
case _iconst_1:
// SET_STACK_INT(1, 0);
stack[top_of_stack] = 1;
// UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);
program_counter += 1;
top_of_stack += 1;
break;
case _iadd:
// SET_STACK_INT(VMintAdd(STACK_INT(-2), STACK_INT(-1)), -2);
stack[top_of_stack - 2] = stack[top_of_stack - 1] + stack[top_of_stack - 2];
// UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
program_counter += 1;
top_of_stack += -1;
break;
}
因此,对于1,操作顺序为:
stack[0] = 1;
stack[1] = 1;
stack[0] = stack[1] + stack[0];
堆栈的顶部将是1,因此我们将以一个包含值2的堆栈作为其唯一元素结束。
问题内容: 我对JVM有一个非常基本的问题:它是编译器还是解释器? 如果它是解释器,那么JVM内部存在的JIT编译器怎么办? 如果两者都不是,那么JVM到底是什么?(我不希望将字节码转换为机器特定的代码等jVM的基本定义。) 问题答案: 首先,让我们对以下术语有一个清晰的认识 是Java编译器-将Java代码编译为 Bytecode 是Java虚拟机-运行/解释/将字节码转换为本 机代码 是即时编
我试图理解Java源代码是如何执行的,我对JVM中的JIT编译器究竟是什么感到困惑。首先,让我告诉您我是如何理解从Java源代码到在计算机上执行机器代码的过程的。也许,我在这一过程中误解了一些导致混淆的东西。 步骤如下: 源代码被编译成字节码(.class文件) 现在,根据维基百科关于JVM的文章,更具体地说是“字节码解释器和实时编译器”部分,为了执行Java字节码,您需要一个解释器(但我们有一个
问题内容: 我正在学习Java,以下内容对我来说有些混乱。我了解的是: Java编译器 →Java编译器仅将程序转换为文件,这意味着将我们的源代码转换为字节码(这是使Java平台独立的虚拟机(JVM)的操作码的列表)。 Java Interpreter →仅“解释”代码,而 没有 将其转换为本地机器代码。它将一条字节码的每条指令作为一条命令一一执行并执行,而不管同一条指令出现多少次。这就是为什么它
我正在学习Java,下面的事情让我有点困惑。我的理解是: > Java编译器→Java编译器只是将程序转换为文件,这意味着将我们的源代码转换为字节码(它是虚拟机(JVM)的操作代码列表,使Java平台独立)。 Java解释器→只是“解释”代码,而不是将其转换为本机机器代码。它将字节码的每一条指令作为命令逐一执行并执行,而不管同一条指令发生多少次。这就是为什么它很慢,Java引入了JIT概念。 JI
我知道这依赖于JVM,每个虚拟机都会选择实现它,但我想了解总体概念。 据说对于JVM用来执行Java程序的内存段 Java堆栈 不一定用连续内存实现,并且可能都实际分配在操作系统提供的一些堆内存上,这就引出了我的问题。 完全使用JIT机制并将字节码方法编译为本机机器码方法的JVM将这些方法存储在某个地方,那会在哪里?执行引擎(通常用C/C编写)将不得不调用这些JIT编译函数,然而内核不应该允许程序
我有一个关于JVM(Java虚拟机)和JIT(即时)的问题。据我所知,JVM将一个字节码(来自. class扩展文件)作为输入并解释这个字节码。问题是: 当我们说解释时,是指将此字节码转换为机器可读代码(否则编译)? 因此,如果JVM将字节码“编译”为机器可读代码和JIT做基本相同的事情(将字节码转换为机器可读代码(否则编译)),那么使用JIT的优势是什么? 谢谢你的回答。