your programing

MSIL과 Java 바이트 코드의 차이점은 무엇입니까?

lovepro 2020. 10. 12. 08:01
반응형

MSIL과 Java 바이트 코드의 차이점은 무엇입니까?


저는 .Net을 처음 사용하고 기본 사항을 먼저 이해하려고 노력하고 있습니다. MSIL과 Java 바이트 코드의 차이점은 무엇입니까?


먼저 Java 바이트 코드와 MSIL의 미묘한 차이가 초보 .NET 개발자를 귀찮게해야한다고 생각하지 않습니다. 둘 다 최종적으로 사용되는 물리적 머신 위의 레이어 인 추상 타겟 머신을 정의하는 동일한 목적을 수행합니다.

MSIL과 Java 바이트 코드는 매우 유사합니다. 사실 MSIL을 Java 바이트 코드로 변환하는 Grasshopper 라는 도구가 있습니다. 저는 Grasshopper 개발 팀의 일원이어서 제 (흐린) 지식을 공유 할 수 있습니다. .NET 프레임 워크 2.0이 나왔을 때이 문제에 대한 작업을 중단 했으므로 이러한 사항 중 일부는 더 이상 사실이 아닐 수 있습니다 (만약 그렇다면 의견을 남겨 주시면 수정하겠습니다).

  • .NET에서는 일반 참조 의미 체계 ( struct) 에 따라 값 의미 체계가있는 사용자 정의 형식을 사용할 수 있습니다 .
  • .NET은 서명되지 않은 유형을 지원하므로 명령어 세트가 조금 더 풍부 해집니다.
  • Java는 바이트 코드에 메소드의 예외 사양을 포함합니다. 예외 사양은 일반적으로 컴파일러에 의해서만 적용되지만 기본 클래스가 아닌 다른 클래스 로더가 사용되는 경우 JVM에서 적용 할 수 있습니다.
  • .NET 제네릭은 IL로 표현되는 반면 Java 제네릭은 유형 삭제 만 사용 합니다 .
  • .NET 속성은 Java에서 동등하지 않습니다 (여전히 사실입니까?).
  • .NET enums은 정수 유형을 둘러싼 래퍼에 지나지 않지만 Javaenums 는 거의 완전한 클래스입니다 ( 주석에 대한 Internet Friend 덕분에 ).
  • .NET에는 outref매개 변수가 있습니다.

다른 언어 차이가 있지만 대부분은 바이트 코드 레벨에서 표현되지 않습니다. 예를 들어 메모리가 Java의 비 static내부 클래스 (.NET에 존재하지 않음)가 바이트 코드 기능이 아닌 경우 컴파일러는 다음에 대한 추가 인수를 생성합니다. 내부 클래스의 생성자이고 외부 객체를 전달합니다. .NET 람다 식도 마찬가지입니다.


그들은 본질적으로 똑같은 일을하고 있으며 MSIL은 Microsoft의 Java 바이트 코드 버전입니다.

내부적으로 주요 차이점은 다음과 같습니다.

  1. 바이트 코드는 컴파일과 해석 모두를 위해 개발되었으며 MSIL은 JIT 컴파일을 위해 명시 적으로 개발되었습니다.
  2. MSIL은 여러 언어 (C # 및 VB.NET 등)를 지원하도록 개발되었으며, Bytecode는 Java 전용으로 작성되었으므로 Bytecode는 IL이 특정 .NET 언어에 대한 것보다 구문 적으로 Java와 더 유사합니다.
  3. MSIL은 값과 참조 유형 사이에 더 명확한 설명이 있습니다.

더 많은 정보와 자세한 비교는 K John Gough (포스트 스크립트 문서) 의이 기사 에서 찾을 수 있습니다.


CIL (MSIL의 고유 이름)과 Java 바이트 코드는 서로 다른 것보다 동일합니다. 하지만 몇 가지 중요한 차이점이 있습니다.

1) CIL은 처음부터 여러 언어의 대상 역할을하도록 설계되었습니다. 따라서 서명 된 형식과 서명되지 않은 형식, 값 형식, 포인터, 속성, 대리자, 이벤트, 제네릭, 단일 루트가있는 개체 시스템 등을 포함하여 훨씬 더 풍부한 형식 시스템을 지원합니다. CIL은 전역 함수 및 마무리 호출 최적화 와 같은 초기 CLR 언어 (C # 및 VB.NET)에 필요하지 않은 기능을 지원합니다 . 비교에서 Java 바이트 코드는 Java 언어의 대상으로 설계되었으며 Java 자체에서 발견되는 많은 제약 조건을 반영합니다. Java 바이트 코드를 사용하여 C 또는 Scheme을 작성하는 것이 훨씬 더 어려울 것입니다.

2) CIL은 네이티브 라이브러리 및 관리되지 않는 코드에 쉽게 통합되도록 설계되었습니다.

3) Java 바이트 코드는 해석되거나 컴파일되도록 설계되었으며 CIL은 JIT 컴파일만을 가정하여 설계되었습니다. 즉, Mono 의 초기 구현은 JIT 대신 인터프리터를 사용했습니다.

4) CIL은 바이트 코드 형식에 직접 매핑되는 사람이 읽고 쓸 수있는 어셈블리 언어 형식을 갖도록 설계 ( 및 지정 )되었습니다. 나는 Java 바이트 코드가 (이름에서 알 수 있듯이) 기계가 읽을 수만 있음을 의미한다고 생각합니다. 물론, 자바 바이트 코드는 비교적 쉽게 원래 자바로 역 컴파일되며, 아래에 표시된 것처럼 "분해"될 수도 있습니다.

JVM (대부분)은 CLR (모두)보다 고도로 최적화되어 있습니다. 따라서 원시 성능은 Java 바이트 코드를 선호하는 이유가 될 수 있습니다. 이것은 구현 세부 사항입니다.

어떤 사람들은 Java 바이트 코드가 다중 플랫폼으로 설계되었지만 CIL은 Windows 전용으로 설계되었다고 말합니다. 그렇지 않다. .NET 프레임 워크에는 몇 가지 "Windows"ism이 있지만 CIL에는 없습니다.

위의 4) 번 포인트의 예로, 나는 얼마 전에 장난감 자바를 CIL 컴파일러에 썼다. 이 컴파일러에 다음 Java 프로그램을 제공하는 경우 :

class Factorial{
    public static void main(String[] a){
    System.out.println(new Fac().ComputeFac(10));
    }
}

class Fac {
    public int ComputeFac(int num){
    int num_aux ;
    if (num < 1)
        num_aux = 1 ;
    else 
        num_aux = num * (this.ComputeFac(num-1)) ;
    return num_aux ;
    }
}

내 컴파일러는 다음 CIL을 뱉어냅니다.

.assembly extern mscorlib { }
.assembly 'Factorial' { .ver  0:0:0:0 }
.class private auto ansi beforefieldinit Factorial extends [mscorlib]System.Object
{
   .method public static default void main (string[] a) cil managed
   {
      .entrypoint
      .maxstack 16
      newobj instance void class Fac::'.ctor'()
      ldc.i4 3
      callvirt instance int32 class Fac::ComputeFac (int32)
      call void class [mscorlib]System.Console::WriteLine(int32)
      ret
   }
}

.class private Fac extends [mscorlib]System.Object
{
   .method public instance default void '.ctor' () cil managed
   {
      ldarg.0
      call instance void object::'.ctor'()
      ret
   }

   .method public int32 ComputeFac(int32 num) cil managed
   {
      .locals init ( int32 num_aux )
      ldarg num
      ldc.i4 1
      clt
      brfalse L1
      ldc.i4 1
      stloc num_aux
      br L2
   L1:
      ldarg num
      ldarg.0
      ldarg num
      ldc.i4 1
      sub
      callvirt instance int32 class Fac::ComputeFac (int32)
      mul
      stloc num_aux
   L2:
      ldloc num_aux
      ret
   }
}

이것은 ilasm.exe실행 파일을 생성하기 위해 CIL 어셈블러에 공급할 수있는 유효한 CIL 프로그램입니다 . 보시다시피 CIL은 완전히 사람이 읽고 쓸 수있는 언어입니다. 모든 텍스트 편집기에서 유효한 CIL 프로그램을 쉽게 만들 수 있습니다.

javac컴파일러를 사용하여 위의 Java 프로그램을 컴파일 한 다음 javap"디스어셈블러"를 통해 결과 클래스 파일을 실행 하여 다음을 얻을 수도 있습니다.

class Factorial extends java.lang.Object{
Factorial();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   new #3; //class Fac
   6:   dup
   7:   invokespecial   #4; //Method Fac."<init>":()V
   10:  bipush  10
   12:  invokevirtual   #5; //Method Fac.ComputeFac:(I)I
   15:  invokevirtual   #6; //Method java/io/PrintStream.println:(I)V
   18:  return

}

class Fac extends java.lang.Object{
Fac();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public int ComputeFac(int);
  Code:
   0:   iload_1
   1:   iconst_1
   2:   if_icmpge   10
   5:   iconst_1
   6:   istore_2
   7:   goto    20
   10:  iload_1
   11:  aload_0
   12:  iload_1
   13:  iconst_1
   14:  isub
   15:  invokevirtual   #2; //Method ComputeFac:(I)I
   18:  imul
   19:  istore_2
   20:  iload_2
   21:  ireturn
}

The javap output is not compilable (to my knowledge) but if you compare it to the CIL output above you can see that the two are very similar.


CIL aka MSIL is intended to be human-readable. Java bytecode is not.

Think of Java bytecode as being machine code for hardware that does not exist (but which JVMs emulate).

CIL is more like assembly language - one step from machine code, while still being human-readable.


There are not that much differences. Both are intermediate formats of the code you wrote. When executed, the Virtual machines will execute the intermediate language managed that means that the Virtual Machine controls the variables and calls. There is even a language which I don't remeber right now that can run at .Net and Java the same way.

Basicly, it's just another format for the same thing

Edit: Found the language (besides Scala): It's FAN (http://www.fandev.org/), looks very interesting, but no time yet to evaluate


Agreed, the differences are minute enough to ingore as a beginner. If you want to learn .Net starting from the basics, I'd recommend looking at the Common Language Infrastructure, and the Common Type System.


Serge Lidin authored a decent book on the details of MSIL: Expert .NET 2.0 IL Assembler. I also was able to pick up MSIL quickly by looking at simple methods using .NET Reflector and Ildasm (Tutorial).

The concepts between MSIL and Java bytecode are very similar.


I think MSIL should not compare to Java bytecode, but "the instruction that comprise the Java bytecodes".

There is no name of disassembled java bytecode. "Java Bytecode" should be an unofficial alias, as I cannot find its name in official document. The Java Class File Disassembler say

Prints out disassembled code, i.e., the instructions that comprise the Java bytecodes, for each of the methods in the class. These are documented in the Java Virtual Machine Specification.

Both "Java VM instructions" and "MSIL" are assembled into .NET bytecode and Java code, which are not human readable.

참고URL : https://stackoverflow.com/questions/95163/differences-between-msil-and-java-bytecode

반응형