문제

일종의 질문에 대한 후속 조치로 MSIL과 Java 바이트 코드의 차이점?, Java Virtual Machine의 작동 방식과 어떻게 .넷 프레임 워크 CLR (Common Language Runtime)이 작동합니까?

또한, .넷 프레임 워크 CLR "가상 머신"또는 가상 머신의 속성이 없습니까?

도움이 되었습니까?

해결책

두 구현 사이에는 많은 유사점이 있습니다 (제 생각에는 : 예, 둘 다 "가상 머신").

우선, 그들은 X86 또는 PowerPC와 같은 현대식 CPU에서 보는 데 익숙한 것처럼 "레지스터"라는 개념이없는 스택 기반 VM입니다. 모든 표현식 ((1 + 1) / 2)의 평가는 피연산자를 "스택"에 밀어 넣은 다음 명령 (추가, 나누기 등)이 해당 피연산자를 소비 할 필요가있을 때마다 스택에서 오페라를 팝업하여 수행됩니다. 각 명령어는 결과를 스택으로 다시 밀어 넣습니다.

전 세계의 거의 모든 CPU가 스택이 있지만 레지스터 수는 종종 다르기 때문에 가상 머신을 구현하는 편리한 방법입니다. 일부 레지스터는 종종 다르기 때문에 (일부 레지스터는 특수 목적이며, 각 명령어는 다른 레지스터의 오페라 등을 기대합니다. ).

따라서 추상 기계를 모델링하려면 순수한 스택 기반 모델이 꽤 좋은 방법입니다.

물론 실제 기계는 그런 식으로 작동하지 않습니다. 따라서 JIT 컴파일러는 바이트 코드 작업의 "등록"을 수행 할 책임이 있으며, 본질적으로 실제 CPU 레지스터를 가능할 때마다 피연산자 및 결과를 포함하도록 예약합니다.

그래서 나는 그것이 CLR과 JVM 사이의 가장 큰 공통점 중 하나라고 생각합니다.

차이점은 ...

두 구현의 흥미로운 차이점 중 하나는 CLR에 일반 유형을 생성 한 다음 해당 유형에 매개 변수 전문화를 적용하는 데 대한 지침이 포함되어 있다는 것입니다. 따라서 런타임에 CLR은 목록을 고려합니다.u003Cint> 목록과는 완전히 다른 유형이됩니다u003CString> .

표지 아래에서는 모든 참조 유형 전문화에 동일한 MSIL을 사용합니다 (따라서 목록u003CString> 목록과 동일한 구현을 사용합니다u003CObject> , API 경계에서 다른 유형 캐스트를 가진) 그러나 각 값 유형은 고유 한 구현을 사용합니다 (목록u003Cint> 목록에서 완전히 다른 코드를 생성합니다u003Cdouble> ).

Java에서는 일반적인 유형이 순전히 컴파일러 트릭입니다. JVM에는 어떤 클래스에 유형의 학습이 있는지 개념이 없으며 런타임에 매개 변수 전문화를 수행 할 수 없습니다.

실제적인 관점에서 볼 때, 이는 일반 유형에서 Java 메소드를 과부하 할 수 없다는 것을 의미합니다. 동일한 이름으로 두 가지 다른 방법을 가질 수 없습니다. 목록을 수락하는지에 대해서만 다릅니다.u003CString> 또는 목록u003CDate> . 물론 CLR은 파라 메트릭 유형에 대해 알고 있으므로 일반 유형 전문화에 과부하 된 방법은 없습니다.

매일 CLR과 JVM 사이에 가장 많이 알 수있는 차이점입니다.

다른 중요한 차이점은 다음과 같습니다.

  • CLR에는 폐쇄가 있습니다 (C# 대표로 구현). JVM은 Java 8 이후에만 폐쇄를 지원합니다.

  • CLR에는 코 루틴이 있습니다 (C# '수율'키워드로 구현). JVM은 그렇지 않습니다.

  • CLR은 사용자 코드를 통해 새로운 값 유형 (structs)을 정의 할 수있는 반면, JVM은 고정 된 값 유형 (바이트, 짧은, int, long, float, double, double, char, boolean)을 제공하고 사용자가 새로운 참조를 정의 할 수 있습니다. 유형 (클래스).

  • CLR은 포인터를 선언하고 조작하는 것을 지원합니다. JVM과 CLR이 모두 메모리 관리 전략으로 엄격한 세대의 압축 쓰레기 수집기 구현을 사용하기 때문에 특히 흥미 롭습니다. 일반적인 상황에서 엄격한 압축 GC는 포인터에 어려움을 겪고 있습니다. 한 메모리 위치에서 다른 메모리 위치로 값을 이동할 때 모든 포인터 (및 포인터로의 포인터)가 유효하지 않기 때문입니다. 그러나 CLR은 "고정"메커니즘을 제공하므로 개발자가 CLR이 특정 포인터를 이동할 수없는 코드 블록을 선언 할 수 있습니다. 매우 편리합니다.

  • JVM에서 가장 큰 코드 단위는 '보호 된'키워드에 의해 입증 된 '패키지'또는 클래스 경로에서 항아리를 지정하고 폴더처럼 취급 할 수있게함으로써 입증 된 바와 같이 '패키지'입니다. 코드. CLR에서 클래스는 '어셈블리'로 집계되며 CLR은 어셈블리에 대한 추론 및 조작에 대한 논리를 제공하여 ( "AppDomains"에로드되어 메모리 할당 및 코드 실행을위한 하위 신청 수준 샌드 박스를 제공 함).

  • CLR 바이트 코드 형식 (MSIL 명령 및 메타 데이터로 구성)은 JVM보다 지침 유형이 적습니다. JVM에서는 모든 고유 한 작업 (두 개의 int 값 추가, 두 개의 플로트 값 추가 등)에는 고유 한 명령이 있습니다. CLR에서 모든 MSIL 지침은 다형성 (두 값 추가)이며 JIT 컴파일러는 피연산자의 유형을 결정하고 적절한 기계 코드를 작성해야합니다. 그래도 바람직한 전략이 무엇인지 모르겠습니다. 둘 다 트레이드 오프가 있습니다. JVM의 핫스팟 JIT 컴파일러는 더 간단한 코드 생성 메커니즘을 사용할 수 있습니다 (이미 명령어에서 인코딩되어 있기 때문에 피연산자 유형을 결정할 필요가 없습니다). 이는보다 복잡한 바이트 코드 형식이 필요하다는 것을 의미합니다. 더 많은 교육 유형이 있습니다.

나는 약 10 년 동안 Java (그리고 JVM에 감탄하는)를 사용해 왔습니다.

그러나 제 생각에는 CLR은 이제 거의 모든면에서 우수한 구현입니다.

다른 팁

첫 번째 질문은 JVM을 .NET 프레임 워크와 비교하는 것입니다. 실제로 CLR과 비교하려고했다고 가정합니다. 그렇다면, 나는 당신이 이것에 대한 작은 책을 쓸 수 있다고 생각합니다 (편집하다: Benji는 이미 가지고있는 것 같습니다 :-)

한 가지 중요한 차이점은 CLR이 JVM과 달리 언어 중립 아키텍처로 설계되었다는 것입니다.

또 다른 중요한 차이점은 CLR이 기본 코드와 높은 수준의 상호 운용성을 허용하도록 특별히 설계되었다는 것입니다. 이는 기본 메모리에 액세스하고 수정할 때 CLR이 신뢰성과 보안을 관리해야하며 또한 마샬링 관리 CLR 기반 데이터 구조와 기본 데이터 구조 사이.

두 번째 질문에 답하기 위해 "가상 머신"이라는 용어는 동일한 종류의 기본 기계의 소프트웨어/하드웨어 에뮬레이션을 의미하는 하드웨어 세계 (예 : 1960 년대 360의 IBM의 가상화)의 오래된 용어입니다. VMware가하는 것들.

CLR은 종종 "실행 엔진"이라고합니다. 이와 관련하여, 이는 x86 위에 IL 기계를 구현 한 것입니다. CLR의 다형 바이트 코드와 JVM의 타입 바이트 코드 사이에는 중요한 차이가 있다고 주장 할 수 있지만 JVM이하는 일이기도합니다.

따라서 두 번째 질문에 대한 pedantic 답변은 "아니오"입니다. 그러나 실제로이 두 용어를 정의하는 방법으로 이어집니다.

편집하다: JVM과 CLR의 한 가지 차이점은 JVM (버전 6)이 매우 꺼려합니다 할당 된 메모리를 운영 체제에 다시 할당 할 수있는 곳에 해제합니다.

예를 들어, JVM 프로세스가 처음에 운영 체제에서 25MB의 메모리를 할당하고 할당한다고 가정 해 봅시다. 그런 다음 앱 코드는 추가 50MB가 필요한 할당을 시도합니다. JVM은 운영 체제에서 추가 50MB를 할당합니다. 응용 프로그램 코드가 해당 메모리 사용을 중단하면 쓰레기가 수집되고 JVM 힙 크기가 줄어 듭니다. 그러나 JVM은 특정 하에서 할당 된 운영 체제 메모리를 자유롭게 할 것입니다. 매우 구체적인 상황. 그렇지 않으면, 나머지 프로세스 수명 동안 그 메모리는 계속 할당됩니다.

반면에 CLR은 더 이상 필요하지 않은 경우 운영 체제에 다시 할당 된 메모리를 다시 출시합니다. 위의 예에서, 힙이 감소하면 CLR이 메모리를 방출했을 것입니다.

차이점에 대한 자세한 내용은 다양한 학업 및 개인 출처에서 찾을 수 있습니다. 좋은 예입니다 CLR 디자인 선택.

몇 가지 구체적인 예는 다음과 같습니다.

  • CLR이 다형성 피연산자를 사용하는 "두 개의 int 추가"와 같은 일부 저수준 Opperand는 입력됩니다. (예 : FADD/IADD/LADD vs just add)
  • 현재 JVM은보다 공격적인 런타임 프로파일 링 및 최적화 (IE 핫스팟)를 수행합니다. CLR은 현재 JIT 최적화를 수행하지만 런타임 최적화는 아닙니다 (예 : 실행 중에 코드를 대체).
  • CLR은 가상 방법을 인라인하지 않습니다. JVM은 ...
  • "프리미티브"를 넘어 CLR의 가치 유형에 대한 지원.

CLR과 JVM은 모두 가상 머신입니다.

.NET 프레임 워크와 Java 런타임 환경은 각 VMS 및 해당 라이브러리의 번들링입니다. 라이브러리가 없으면 VM은 쓸모가 없습니다.

가상 머신이 아니며 .NET 프레임 워크는 첫 번째 실행 시점에 어셈블리를 기본 바이너리로 컴파일합니다.

컴퓨팅에서 동적 변환이라고도하는 JIT (Just-in-Time Compilation)는 컴퓨터 프로그램의 런타임 성능을 향상시키는 기술입니다. JIT는 런타임 환경에서 바이트 코드 컴파일 및 동적 컴파일의 두 가지 초기 아이디어를 기반으로합니다. 기본적으로 실행하기 전에 런타임에 코드를 변환합니다 (예 : Bytecode)는 기본 기계 코드로 코드를 변환합니다. 통역사보다 성능 개선은 코드 블록을 번역 한 결과를 캐싱하는 것으로부터 시작되며, 충족 될 때마다 각 라인이나 오페라를 재평가하지 않습니다 (해석 된 언어 참조). 또한 개발 시간에 코드를 통계적으로 컴파일하는 데 비해 장점이 있으며, 이것이 유리한 것으로 밝혀지면 보안 보증을 시행 할 수있는 코드를 다시 컴파일 할 수 있으므로 코드를 다시 컴파일 할 수 있습니다. 따라서 JIT는 해석과 정적 (미리) 편집의 일부 장점을 결합 할 수 있습니다.

Microsoft의 .NET Framework, 대부분의 Java 구현 및 가장 최근의 ActionScript 3과 같은 몇 가지 최신 런타임 환경은 고속 코드 실행을 위해 JIT 컴파일에 의존합니다.

원천: http://en.wikipedia.org/wiki/just-intime_compilation

.NET 프레임 워크를 추가하면 Java와 마찬가지로 가상 머신이 포함됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top