문제

내 교수님이 작은 프로그램에 대해 비공식 벤치마크를 수행했는데 Java 시간은 다음과 같습니다.첫 번째 실행에는 1.7초, 이후 실행에는 0.8초가 소요됩니다.

  • 이는 전적으로 런타임 환경을 운영 환경으로 로드하기 때문입니까?

    또는

  • Java가 코드를 최적화하고 해당 최적화 결과를 저장하는 것에 영향을 받았나요(죄송합니다. 이에 대한 기술 용어는 모르겠습니다).

도움이 되었습니까?

해결책

포스터에서 볼 수 있는 성능 차이는 JRE를 메모리로 가져오는 디스크 대기 시간으로 인해 발생할 가능성이 높다는 데 동의합니다.JIT(Just In Time 컴파일러)는 작은 애플리케이션의 성능에 영향을 미치지 않습니다.

자바 1.6u10(http://download.java.net/jdk6/)는 백그라운드 프로세스에서 런타임 JAR을 처리하여(Java가 실행되지 않는 경우에도) 디스크 캐시에 데이터를 유지합니다.이로 인해 시작 시간이 크게 단축됩니다(데스크탑 앱에는 큰 이점이지만 서버 측 앱에는 미미한 가치일 수 있습니다).

대규모의 장기 실행 애플리케이션에서 JIT는 시간이 지남에 따라 큰 차이를 만듭니다. 그러나 JIT가 실행 및 최적화를 위한 충분한 통계를 축적하는 데 필요한 시간(5~10초)은 전체 수명에 비해 매우 짧습니다. 응용 프로그램의 (대부분 몇 달 동안 실행됨)JIT 결과를 저장하고 복원하는 것은 흥미로운 학술 활동이지만 실질적인 개선은 그리 크지 않습니다(이것이 JIT 팀이 메모리 캐시 누락을 최소화하기 위한 GC 전략과 같은 것에 더 집중한 이유입니다...).

런타임 클래스의 사전 컴파일은 데스크톱 애플리케이션에 상당한 도움이 됩니다(앞에서 언급한 6u10 디스크 캐시 사전 로드와 마찬가지로).

다른 팁

좋아, 내가 읽은 곳을 찾았어.이것은 모두 "Learning Java"(O'Reilly 2005)에서 가져온 것입니다.

기존 JIT 컴파일의 문제점은 코드 최적화에 시간이 걸린다는 것입니다.따라서 JIT 컴파일러는 괜찮은 결과를 생성할 수 있지만 애플리케이션이 시작될 때 상당한 대기 시간이 발생할 수 있습니다.이는 일반적으로 오랫동안 실행되는 서버측 애플리케이션에는 문제가 되지 않지만 제한된 기능을 갖춘 소형 장치에서 실행되는 클라이언트측 소프트웨어 및 애플리케이션에는 심각한 문제입니다.이 문제를 해결하기 위해 HotSpot이라고 하는 Sun의 컴파일러 기술은 적응형 컴파일이라는 기술을 사용합니다.실제로 어떤 프로그램을 수행하는 데 시간을 소비하는지 살펴보면 비교적 작은 코드 부분을 계속해서 실행하는 데 거의 모든 시간을 소비한다는 사실이 밝혀졌습니다.반복적으로 실행되는 코드 덩어리는 전체 프로그램의 작은 부분일 수 있지만 해당 동작에 따라 프로그램의 전체 성능이 결정됩니다.또한 적응형 컴파일을 통해 Java 런타임은 정적으로 컴파일된 언어에서는 수행할 수 없는 새로운 종류의 최적화를 활용할 수 있으므로 경우에 따라 Java 코드가 C/C++보다 빠르게 실행될 수 있다고 주장됩니다.

이 사실을 활용하기 위해 HotSpot은 일반적인 Java 바이트코드 해석기로 시작하지만 차이점이 있습니다.어떤 부분이 반복적으로 실행되고 있는지 확인하기 위해 실행되는 동안 코드를 측정(프로파일링)합니다.코드의 어떤 부분이 성능에 중요한지 파악하면 HotSpot은 해당 섹션을 최적의 기본 기계어 코드로 컴파일합니다.프로그램의 작은 부분만 기계어 코드로 컴파일하기 때문에 해당 부분을 최적화하는 데 필요한 시간을 가질 수 있습니다.프로그램의 나머지 부분은 전혀 컴파일할 필요가 없으며 해석만 하면 되기 때문에 메모리와 시간이 절약됩니다.실제로 Sun의 기본 Java VM은 다음 두 가지 모드 중 하나로 실행될 수 있습니다.클라이언트와 서버는 빠른 시작 시간과 메모리 보존을 강조할지 또는 성능을 평준화할지 여부를 알려줍니다.

이 시점에서 물어볼 자연스러운 질문은 '왜 애플리케이션이 종료될 때마다 이 좋은 프로파일링 정보를 모두 버리는가?'입니다.Sun은 최적화된 형식으로 지속적으로 저장되는 공유 읽기 전용 클래스를 사용하여 Java 5.0 릴리스에서 이 주제를 부분적으로 다루었습니다.이는 특정 시스템에서 많은 Java 애플리케이션을 실행하는 데 따른 시작 시간과 오버헤드를 크게 줄여줍니다.이를 수행하는 기술은 복잡하지만 아이디어는 간단합니다.빠르게 진행해야 하는 프로그램 부분을 최적화하고 나머지 부분은 걱정하지 마세요.

Java 5.0 이후 Sun이 이를 얼마나 활용해왔는지 궁금합니다.

프로그램 호출 사이에 통계적 사용 데이터를 저장하는 가상 머신이 널리 사용되는 것은 아니지만 향후 연구를 위한 흥미로운 가능성임은 분명합니다.

지금 보고 있는 현상은 디스크 캐싱으로 인한 것이 거의 확실합니다.

디스크 캐싱의 결과일 가능성이 높다는 데 동의합니다.

참고로 IBM Java 6 VM에는 AOT(Ahead-of-Time 컴파일러)가 포함되어 있습니다.코드는 JIT가 생성하는 것만큼 최적화되지는 않지만 VM 전체에 저장되므로 일종의 영구 공유 메모리라고 믿습니다.주요 이점은 시작 성능을 향상시키는 것입니다.IBM VM은 기본적으로 메소드가 1000번 호출된 후 JIT합니다.VM 시작 중에 메소드가 1000번 호출될 것이라는 것을 알고 있다면(일반적으로 사용되는 메소드를 생각해 보십시오. java.lang.String.equals(...) ), 런타임 시 컴파일하는 데 시간을 낭비할 필요가 없도록 이를 AOT 캐시에 저장하는 것이 좋습니다.

벤치마크가 어떻게 수행되었는지 설명해야 합니다.특히 시간을 측정하기 시작하는 시점입니다.

JVM 시작 시간(사용자 경험을 벤치마킹하는 데 유용하지만 Java 코드를 최적화하는 데는 유용하지 않음)을 포함하는 경우 파일 시스템 캐싱 효과일 수도 있고 "Java 클래스 데이터 공유"라는 기능으로 인해 발생할 수 있습니다.

썬의 경우:

http://java.sun.com/j2se/1.5.0/docs/guide/vm/class-data-sharing.html

이는 JVM이 런타임 클래스의 준비된 이미지를 파일에 저장하여 다음 시작 시 해당 이미지를 더 빠르게 로드(및 공유)할 수 있도록 하는 옵션입니다.Sun JVM에서 -Xshare:on 또는 -Xshare:off를 사용하여 이를 제어할 수 있습니다.기본값은 -Xshare:auto이며, 공유 클래스 이미지가 있는 경우 이를 로드하고, 존재하지 않는 경우 디렉터리에 쓰기 가능한 경우 처음 시작할 때 이를 씁니다.

IBM Java 5를 사용하면 BTW가 더욱 강력해집니다.

http://www.ibm.com/developerworks/java/library/j-ibmjava4/

나는 JIT 통계를 저장하는 주류 JVM을 모릅니다.

Java JVM(실제로는 JVM의 다른 구현에서 변경될 수 있음)은 처음 시작할 때 바이트 코드를 해석합니다.코드가 충분한 횟수만큼 실행될 것임을 감지하면 기본 기계 언어로 JIT하여 더 빠르게 실행됩니다.

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