我对JIT编译器的工作原理有点困惑.我知道C#编译成IL.第一次运行它是JIT'd.这是否涉及将其翻译成本机代码?.NET运行时(作为虚拟机吗?)是否与JIT代码交互?我知道这很天真,但我真的很困惑.我的印象一直是.NET运行时没有解释程序集,但我不了解交互的细节.
我真的很难理解以下事情
以前我知道:
编译Java程序时.class将生成文件.在那个代码是字节的形式.然后将该JVM字节代码转换为机器可理解的格式.
Just-In-Time(JIT)编译器是运行时解释器的一个特性,它不是在每次调用方法时解释字节码,而是将字节码编译成运行机器的机器代码指令.
所以这里JIT将字节码转换为机器指令.那么JVM的用途是什么.我们可以用JIT做到这一点.据我所知,JIT仅用于提高JVM的性能.
为简单起见,想象一下这种情况,我们有一台2位计算机,它有一对2位寄存器,称为r1和r2,只适用于立即寻址.
让我们说比特序列00意味着添加到我们的CPU.也01的装置将数据移动到R 1和10组的装置将数据移动到R2.
因此,这台计算机和汇编程序有一个汇编语言,其中的示例代码将被编写为
mov r1,1
mov r2,2
add r1,r2
Run Code Online (Sandbox Code Playgroud)
简单地说,当我将此代码汇编为本机语言时,文件将类似于:
0101 1010 0001
Run Code Online (Sandbox Code Playgroud)
上面的12位是本机代码:
Put decimal 1 to R1, Put decimal 2 to R2, Add the data and store in R1.
Run Code Online (Sandbox Code Playgroud)
所以这基本上是编译代码的工作方式,对吧?
让我们说有人为这个架构实现了一个JVM.在Java中,我将编写如下代码:
int x = 1 + 2;
Run Code Online (Sandbox Code Playgroud)
JVM将如何解释此代码?我的意思是最终必须将相同的位模式传递给cpu,不是吗?所有cpu都有许多可以理解和执行的指令,它们毕竟只是一些位.让我们说编译的Java字节码看起来像这样:
1111 1100 1001
Run Code Online (Sandbox Code Playgroud)
或者其他..是否意味着解释在执行时将此代码更改为0101 1010 0001?如果是,它已经在本机代码中了,那为什么说JIT只是经过多次启动?如果它没有完全转换为0101 1010 0001,那么它会做什么?它如何使cpu做添加?
也许我的假设存在一些错误.
我知道解释很慢,编译代码更快但不可移植,虚拟机"解释"代码,但是如何?我正在寻找"如何完全/技术解释".任何指针(如书籍或网页)都是受欢迎的,而不是答案.
所以我的问题更为笼统.我有以下简单的代码:
for(int i=0;i<10;i++){
long starttime=System.nanoTime();
System.out.println("test");
long runtime=System.nanoTime()-starttime;
System.out.println(i + ":" +"runtime="+runtime);
}
Run Code Online (Sandbox Code Playgroud)
我收到以下输出:
test
0:runtime=153956
test
1:runtime=15396
test
2:runtime=22860
test
3:runtime=11197
test
4:runtime=11197
test
5:runtime=12129
test
6:runtime=11663
test
7:runtime=11664
test
8:runtime=53185
test
9:runtime=12130
Run Code Online (Sandbox Code Playgroud)
第一个和第二个运行时区别的原因是什么?提前感谢=)
我的问题是将IL转换为Machine语言的JIT编译器是完全是编译器还是解释器.
还有一个问题:HTML,JavaScript是编译语言还是解释语言?
提前致谢
Building是由编译和链接组成的序列.
在.NET中,源代码被编译到包含公共中间语言和类型信息的程序集中.在运行时,JIT编译器将CIL代码转换为本机代码.
我不明白,在.NET中,链接是如何以及何时发生的.
有人可以解释一下这个过程吗?
提前致谢
我一直在弄清楚翻译的确切工作,搜索过并得出一些结论,只是希望能够让我更好地理解翻译工作的人来纠正它.
所以我所理解的是:
现在我仍然不清楚在...之间发生的子过程
还有一些问题:
所以我要问每个网络浏览器都有自己的编译器示例IE从网站编译Javascript并生成字节码的序列A.
另一方面,谷歌浏览器从同一网站编译相同的Javascript并生成序列B.
我想知道这一点,因为如果是这样的话,在Javascript上运行编译器并将生成的字节代码上传到网站而不是Javascript本身是有益的.并根据每个浏览器发送不同的字节码.
还是有其他一些限制.
我理解JIT编译的工作原理(在阅读了这个SO问题之后的资源).但是,我仍然想知道它是如何在运行时实际执行机器代码的?
我没有深入的操作系统或编译器优化背景,也没有直接使用机器代码做任何事情,但我开始探索它.我已经开始在汇编中玩,看看像NASM这样的东西可以把你的汇编代码编译成机器代码(可执行文件),然后你可以从命令行"调用"它./my-executable.
但是JIT编译器在运行时实际上是如何做到的呢?是将流机器代码转换为stdin还是其他东西,或者它是如何工作的?如果你可以提供一个例子或一些伪代码来说明某些程序集(或那些沿着这些行的东西,而不是像C那样高的程度)可能看起来可以展示基本流程,那也是惊人的.
我上课了
class A {
private int x;
public void setX(...){...}
public int getX(){return x;}
}
class B {
int y;
public void setY() {
//Accessing x of A, assume I already have object of A
if(a.getX() < 0) {
y = a.getX();
}
}
}
class C {
int y;
public void setY() {
//Accessing x of A, assume I already have object of A
int tmpX = a.getX();
if(tmpX < 0) {
y = tmpX;
}
}
}
Run Code Online (Sandbox Code Playgroud)
哪一个是更好的编码方式?我 …
编译器是否编译了一个简单的三元语句,以便编译一个简单的if else语句?另外,为什么编译器会被设计为以不同方式编译它们?
例如,这样:
int a = 169;
int b = 420;
int c;
c = a > b ? 42:69;
Run Code Online (Sandbox Code Playgroud)
编译成同样的东西:
int a = 169;
int b = 420;
int c;
if(a>b) c = 42;
else c = 69;
Run Code Online (Sandbox Code Playgroud)
这个问题不是关于哪个更好或何时使用每个问题,所以请不要在答案中包含这个问题.
java ×6
jit ×4
c# ×3
compilation ×3
interpreter ×3
.net ×2
jvm ×2
browser ×1
build ×1
bytecode ×1
javascript ×1
linker ×1
llvm ×1
machine-code ×1
nanotime ×1
performance ×1
system ×1