JVM이 JIT 컴파일 코드를 캐시하지 않는 이유는 무엇입니까?
Sun의 표준 JVM 구현은 바이트 코드에 매우 정교한 최적화를 적용하여 코드가 몇 번 실행된 후 네이티브에 가까운 실행 속도를 얻습니다.
문제는 이 컴파일된 코드가 이후 동일한 함수/클래스를 사용할 때 사용할 수 있도록 디스크에 캐시되지 않는 이유는 무엇입니까?
현재 상태에서는 프로그램이 실행될 때마다 JIT 컴파일러는 미리 컴파일된 버전의 코드를 사용하지 않고 새로 시작합니다.이 기능을 추가하면 바이트 코드가 기본적으로 해석되는 프로그램의 초기 실행 시간이 크게 향상되지 않을까요?
@MYN이 게시한 링크의 컷 앤 페이스트에 의존하지 않고 JVM이 수행하는 최적화는 정적인 것이 아니라 데이터 패턴과 코드 패턴을 기반으로 동적이기 때문이라고 생각합니다.이러한 데이터 패턴은 애플리케이션 수명 동안 변경되어 캐시된 최적화가 최적화되지 않을 수 있습니다.
따라서 저장된 최적화가 여전히 최적의지 여부를 확인하는 메커니즘이 필요합니다. 이때 즉시 다시 최적화하는 것이 좋습니다.
Oracle의 JVM은 실제로 이를 문서화하고 있습니다(Oracle,
컴파일러는 Oracle JVM의 클래스 해결 모델을 이용하여 선택적으로 컴파일된 Java 메서드를 데이터베이스 호출, 세션 또는 인스턴스에서 유지할 수 있습니다.이러한 지속성을 통해 Java 코드가 의미적으로 변경되지 않은 것으로 알려진 경우 세션 또는 인스턴스 간에 불필요한 재컴파일 오버헤드를 피할 수 있습니다.
왜 모든 고급 VM 구현에서 유사한 옵션을 제공하지 않는지 모르겠습니다.
기존 답변 업데이트 - Java 8에는 이 문제를 해결하기 위한 JEP가 있습니다.
=> JEP 145: 캐시 컴파일 코드.새 링크
매우 높은 수준에서 이 회사의 목표는 다음과 같습니다.
이전 실행에서 컴파일된 네이티브 코드를 저장하고 재사용하여 대형 Java 응용 프로그램의 부팅 시간을 단축합니다.
이게 도움이 됐으면 좋겠다.
Excelsior JET에는 2001년에 출시된 버전 2.0 이후 캐싱된 JIT 컴파일러가 있습니다.또한 AOT 컴파일러는 모든 최적화를 사용하여 캐시를 단일 DLL/공유 객체로 재컴파일할 수 있습니다.
JVM의 실장에 관여하고 있지 않기 때문에, 실제의 이유는 알 수 없지만, 몇개의 타당한 이유를 생각할 수 있습니다.
- Java의 개념은 write-on-run-anywhere 언어이며, 클래스 파일에 미리 컴파일된 내용을 넣는 것은 이를 위반하는 것입니다(물론 실제 바이트 코드는 아직 존재하기 때문에 "일종의"일 뿐입니다).
- 같은 코드가 여러 번 존재하기 때문에 클래스 파일사이즈가 커집니다.특히 같은 프로그램을 여러 개의 다른 JVM에서 실행하는 경우는 드물지 않습니다(다른 버전을 다른 JVM으로 간주할 때는 반드시 실행해야 합니다).
- 클래스 파일 자체는 쓰기 불가능할 수 있습니다(단, 확인은 매우 간단함).
- JVM 최적화는 부분적으로 런타임 정보를 기반으로 하며, 다른 실행에서는 해당되지 않을 수 있습니다(다만 일부 이점이 있습니다).
하지만 저는 정말 추측하고 있습니다. 보시다시피 제 이유 중 어떤 것도 실제 쇼 스토퍼라고 생각하지 않습니다.Sun은 이 지원을 우선으로 여기지 않습니다.아마도 첫 번째 이유는 사실일 것입니다.이렇게 하면 Java 클래스 파일을 크로스 플랫폼이 아닌 VM별로 별도의 버전이 필요하다는 생각이 들 수 있기 때문입니다.
이러한 작업을 명시적으로 수행하기 위해 사용할 수 있는 별도의 바이트 코드-네이티브 변환기를 사용하는 것이 바람직합니다.이 변환기는 특정 VM용으로 명시적으로 구축되어 있는 클래스 파일입니다.아마도 원래의 바이트 코드가 포함되어 있기 때문에 다른 VM에서도 실행할 수 있습니다.하지만 그건 아마 내 경험에서 비롯된 것일 거야.저는 자바 ME를 주로 하고 있는데, 자바 컴파일러가 컴파일러에 대해 더 똑똑하지 않다는 점이 정말 마음에 안 들어요.
언급URL : https://stackoverflow.com/questions/1992486/why-doesnt-the-jvm-cache-jit-compiled-code
'programing' 카테고리의 다른 글
JSON.stringify의 역방향? (0) | 2022.10.27 |
---|---|
Java 스위치 문: 상수 표현이 필요하지만 IS 상수입니다. (0) | 2022.10.27 |
MySQL의 로드 데이터 파일에 대한 액세스가 거부되었습니다. (0) | 2022.10.08 |
yield()의 주요 용도는 무엇이며 join() 및 interrupt()와는 어떻게 다릅니까? (0) | 2022.10.08 |
사전을 JSON으로 변환하는 중 (0) | 2022.10.08 |