source

Java의 가상 머신 및 CLR

manysource 2022. 11. 23. 20:20

Java의 가상 머신 및 CLR

MSIL과 Java 바이트 코드의 차이라는 질문에 대한 후속 조치로서 Java Virtual Machine의 동작방식에 대한 (주요한) 차이점 또는 유사점은 무엇입니까?NET Framework Common Language Runtime(CLR)은 기능합니까?

, 는 입니다.NET 프레임워크 CLR은 "가상 머신"이거나 가상 머신의 속성이 없습니까?

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

예를 들어 둘 다 스택 기반 VM이며 x86이나 PowerPC와 같은 최신 CPU에서 흔히 볼 수 있는 "레지스터"라는 개념이 없습니다.모든 식(1 + 1) / 2)의 평가는 명령(추가, 분할 등)이 이들 오퍼랜드를 소비할 필요가 있을 때마다 오퍼랜드를 스택에 푸시하고 스택에서 제외함으로써 수행됩니다.각 명령은 결과를 스택에 다시 푸시합니다.

이는 가상 머신을 구현하는 편리한 방법입니다.왜냐하면 전 세계 거의 모든 CPU에 스택이 있기 때문입니다.그러나 레지스터의 수는 종종 다릅니다(또한 일부 레지스터는 특수 용도이며 각 명령에서는 다른 레지스터에 오퍼랜드를 상정하고 있습니다).

따라서 추상 머신을 모델화하려면 순수 스택 기반 모델을 사용하는 것이 좋습니다.

물론 실제 기계는 그런 식으로 작동하지 않습니다.따라서 JIT 컴파일러는 바이트 코드 연산의 "등록"을 수행하고, 가능한 한 오퍼랜드와 결과를 포함하도록 실제 CPU 레지스터를 스케줄링합니다.

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

차이에 대해서는...

두 구현의 흥미로운 차이점 중 하나는 CLR에 범용 유형을 작성하고 그 유형에 파라미터 전문화를 적용하는 지침이 포함되어 있다는 것입니다.따라서 실행 시 CLR은 List <int>를 List <String>과 완전히 다른 유형으로 간주합니다.

여기에서는 모든 참조 타입의 지정에 같은 MSIL을 사용합니다(따라서 List <String>은 List <Object>와 같은 실장을 사용하고 API 경계에 다른 타입 캐스트를 사용합니다).단, 각 값 타입은 독자적인 실장을 사용합니다(List <int>는 List <double>와 완전히 다른 코드를 생성합니다).

Java에서 범용 유형은 순전히 컴파일러 트릭입니다.JVM은 유형 인수가 있는 클래스에 대한 개념이 없으며 런타임에 매개 변수 전문화를 수행할 수 없습니다.

실용적인 관점에서 보면 범용 타입에서는 Java 메서드를 오버로드할 수 없습니다.같은 이름의 2개의 다른 메서드는 List <String> 또는 List <Date> 중 어느 쪽을 받아들이느냐에 따라 다를 수 없습니다.물론 CLR은 파라미터 타입을 인식하고 있기 때문에 범용 타입의 지정으로 오버로드된 메서드를 처리하는 데 문제가 없습니다.

매일 CLR과 JVM의 차이점은 바로 이 점입니다.

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

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

  • CLR에는 Coroutines가 있습니다(C#의 「유효」키워드로 실장되어 있습니다.JVM은 동작하지 않습니다.

  • CLR을 사용하면 사용자 코드가 새로운 값 유형(구조)을 정의할 수 있지만 JVM은 고정 값 유형(바이트, 쇼트, int, 롱, 플로트, 더블, 문자, 부울)을 제공하며 사용자는 새로운 참조 유형(클래스)만 정의할 수 있습니다.

  • CLR은 포인터의 선언 및 조작을 지원합니다.JVM과 CLR 모두 메모리 관리 전략으로 엄격한 세대 압축 가비지 콜렉터 구현을 채택하고 있기 때문에 특히 흥미롭습니다.통상적인 상황에서는 엄밀한 압축 GC는 포인터를 사용하는 데 매우 어려움을 겪습니다.이것은, 메모리 위치간에 값을 이동하면, 모든 포인터(및 포인터)가 무효가 되기 때문입니다.그러나 CLR은 개발자가 특정 포인터를 이동할 수 없는 코드 블록을 선언할 수 있도록 "피닝" 메커니즘을 제공합니다.매우 편리합니다.

  • JVM에서 가장 큰 코드 단위는 'protected' 키워드로 증명된 '패키지'이거나 클래스 경로에서 jar를 지정하고 코드 폴더처럼 처리할 수 있는 것으로 증명된 JAR(즉 Java ARchive)입니다.CLR에서는 클래스가 '어셈블리'로 집약되고 CLR은 어셈블리에 대한 추론 및 조작을 위한 로직을 제공합니다('AppDomains'에 로드되어 메모리 할당 및 코드 실행을 위한 하위 응용 프로그램 수준의 샌드박스를 제공합니다).

  • CLR 바이트 코드 형식(MSIL 명령 및 메타데이터로 구성됨)은 JVM보다 명령 유형이 적습니다.JVM에서는 모든 고유 작업(int 값 2개 추가, float 값 2개 추가 등)에 고유한 명령이 있습니다.CLR에서는 모든 MSIL 명령은 다형성(2개의 값을 추가)이며, JIT 컴파일러는 오퍼랜드의 유형을 결정하고 적절한 머신 코드를 작성합니다.하지만 어떤 것이 더 바람직한 전략인지 모르겠습니다.둘 다 단점이 있다.JVM용 HotSpot JIT 컴파일러는 보다 간단한 코드 생성 메커니즘을 사용할 수 있지만(명령어로 이미 인코딩되어 있기 때문에 오퍼랜드 유형을 결정할 필요는 없습니다), 이는 더 많은 명령 유형을 포함하는 더 복잡한 바이트 코드 형식이 필요하다는 것을 의미합니다.

자바(JVM을 동경하는 것)를 사용해 온 지 약 10년이 되었습니다.

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

첫 번째 질문은 JVM과 를 비교하는 것입니다.NET Framework - 나는 당신이 CLR과 비교하는 것을 의도했다고 생각합니다.만약 그렇다면, 이것에 관한 작은 책을 써 주셨으면 합니다(편집:벤지는 이미 :-를 가지고 있는 것 같습니다).

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

또 다른 중요한 차이점은 CLR이 네이티브코드와의 높은 수준의 상호 운용성을 실현하도록 특별히 설계되었다는 점입니다.즉, 네이티브메모리에 액세스 및 변경 시 CLR이 신뢰성과 보안을 관리해야 하며 CLR 기반 데이터 구조와 네이티브 데이터 구조 간의 마샬링도 관리해야 합니다.

두 번째 질문에 답하자면, "가상 머신"이라는 용어는 하드웨어 세계(예: 1960년대 IBM의 360 가상화)에서 유래한 용어로, VMWare와 동일한 종류의 작업을 수행하기 위해 기본 머신의 소프트웨어/하드웨어 에뮬레이션을 의미했습니다.

CLR은 종종 "실행 엔진"이라고 불립니다.이 경우 x86 위에 IL 머신을 구현한 것입니다.이것은 JVM이 하는 일이기도 합니다만, CLR의 다형 바이트 코드와 JVM의 타입 바이트 코드 사이에는 중요한 차이가 있다고 주장할 수 있습니다.

그래서 당신의 두 번째 질문에 대한 현학적인 대답은 "아니오"입니다.하지만 결국 이 두 용어를 어떻게 정의하느냐에 달려 있습니다.

편집: JVM과 CLR의 또 다른 차이점은 JVM(버전 6)이 할당된 메모리를 운영체제로 되돌리는 것을 매우 꺼린다는 것입니다.

예를 들어 JVM 프로세스가 시작되고 운영 체제에서 25MB의 메모리가 할당된다고 가정합니다.그런 다음 앱 코드는 추가로 50MB가 필요한 할당을 시도합니다.JVM은 운영 체제에서 추가로 50MB를 할당합니다.애플리케이션 코드가 메모리 사용을 중지하면 가비지가 수집되고 JVM 힙 크기가 줄어듭니다.단, JVM은 할당된 운영체제 메모리를 특정 특정 상황에서만 해방합니다.그렇지 않으면 나머지 프로세스 수명 동안 해당 메모리가 할당된 상태로 유지됩니다.

한편, CLR은 할당된 메모리를 더 이상 필요하지 않은 경우 운영체제로 되돌립니다.위의 예에서는 CLR은 히프가 감소하면 메모리를 해방합니다.

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

.NET Framework와 Java Runtime Environment는 각 VM과 해당 라이브러리의 번들링입니다.라이브러리가 없으면 VM은 거의 쓸모가 없습니다.

차이점에 대한 자세한 내용은 다양한 학계와 민간 소식통을 통해 확인할 수 있습니다.한 가지 좋은 예는 CLR 설계 선택 사항입니다.

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

  • CLR이 다형 피연산자를 사용하기 때문에 "add two ints"와 같은 일부 하위 오퍼가 입력됩니다.(예: fadd/iadd/ladd vs just add)
  • 현재 JVM은 보다 적극적인 런타임 프로파일링 및 최적화(즉, 핫스팟)를 수행하고 있습니다.현재 CLR은 JIT 최적화를 수행하지만 런타임 최적화는 수행하지 않습니다(실행 중에 코드를 교체).
  • CLR은 가상 메서드를 인라인화하지 않습니다.JVM은...
  • CLR의 값 유형은 단순히 "원본"을 넘어 지원됩니다.

.net 프레임워크는 첫 번째 실행 시 어셈블리를 네이티브 바이너리로 컴파일합니다.

컴퓨팅에서 JIT(Just-in-time Compilation)는 동적 변환이라고도 하며 컴퓨터 프로그램의 런타임 성능을 향상시키는 기술입니다.JIT는 런타임 환경에서 바이트 코드 컴파일과 동적 컴파일이라는 두 가지 아이디어를 기반으로 합니다.네이티브로 실행하기 전에 런타임에 코드를 변환합니다(예: 바이트 코드).인터프리터보다 퍼포먼스가 향상되는 것은 코드 블록의 변환 결과를 캐싱하는 것으로부터이며, 각 행 또는 오퍼랜드를 만날 때마다 단순히 재평가하는 것이 아닙니다(인터프리터 언어 참조).또, 개발시에 코드를 정적으로 컴파일 하는 것에 비해, 이점이 있습니다.이것이 유리하다고 판단되면 코드를 재컴파일 할 수 있어 시큐러티 보증을 실시할 수 있습니다.따라서 JIT는 해석과 정적(사전) 컴파일의 장점을 결합할 수 있습니다.

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

출처 : http://en.wikipedia.org/wiki/Just-in-time_compilation

합산 중.NET 프레임워크에는 Java와 마찬가지로 가상 시스템이 포함되어 있습니다.

언급URL : https://stackoverflow.com/questions/453610/javas-virtual-machine-and-clr