>source

시간이 지남에 따라 JVM이 더 똑똑해질 것이라는 것을 알고 있습니다 (코드 최적화 등).
그러나 얼마나 더 똑똑 할 수 있습니까?

내가 자주 보는 실제 시나리오를 생각해 봅시다.

public static String toJson(final Object object) throws JsonProcessingException {
   final ObjectMapper mapper = new ObjectMapper();
   return mapper.writeValueAsString(object); 
}

이것을 분석하면, 우리는 ObjectMapper (무겁다 고 생각하는 것)이 메서드가 호출 될 때마다 힙에 생성됩니다.
가비지 수집기에 비용이 많이 듭니다.

그래서 제 질문은 JVM이 충분히 똑똑하고 하나의 인스턴스 (정적 인스턴스와 같은 것)를 만들 수 있습니까?


  • 답변 # 1

    JVM은 Java 언어 사양을 위반하는 정적 객체의 관점에서이 객체를 암시 적으로 공유하지 않습니다. 객체 자체에 멤버가 없더라도 다른 객체와 해당 상태에 의존하면 동작이 변경 될 수 있으며 이는 스레드로부터 안전하지 않을 수 있습니다. 객체가 스레드로부터 안전하거나 코드가 단일 스레드 인 경우에도 구현이 항상 초기 상태에서 시작되는 것은 아니므로 암시 적 재사용은 원래 코드의 가정을 깨뜨릴 수 있습니다.

    객체 할당 자체를 제거하는 경우 특정 상황에서 수행 할 수 있으며 수행 할 수 있습니다. 이스케이프 분석을 통해 JIT는 새로 생성 된 개체에 대한 참조가 다른 힙 개체의 필드에 저장 될 수있는 경우 현재 로컬 변수 집합과 관련하여 이론적으로 현재 프레임을 벗어나거나 "이스케이프"할 수 있는지 여부를 결정할 수 있습니다. 분석 결과 지정된 개체가없는 것으로 확인되면 개체의 수명이 현재 프레임으로 제한되므로 힙 할당을 스택 할당으로 바꿀 수 있습니다.

    Oracle JVM 구현은 이스케이프 분석을 수행 할 수 있지만 힙 할당을 스택 할당으로 대체하지는 않습니다. 대신 "스칼라 교체"라는 최적화를 수행합니다. 즉, 객체 참조가 현재 프레임을 이스케이프하지 않고 모든 호출 된 객체 메서드를 인라인 할 수있는 경우 객체 필드 액세스가 해당 지역 변수로 교체됩니다. 따라서 JVM은 실제 개체 인스턴스를 완전히 제거합니다. 구현에 따라 ObjectMapper ,이 최적화가 귀하의 예에 적용될 수 있습니다.

    자세한 내용은 다음을 참조하십시오.

    https://docs.oracle.com/javase/8/docs/technotes/guides/vm/performance-enhancements-7.html#escapeAnalysis

    문서를 기반으로 객체를 안전하게 공유하고 재사용 할 수 있다는 것을 알고 있다면 가장 좋은 방법은 잠재적 인 최적화에 의존하지 않고 인스턴스를 명시 적으로 재사용하는 것입니다.

  • 답변 # 2

    아뇨. 당신은 이것들을 말해야합니다. JVM이 작동하는 방식을 정확히 배우려면 Java 언어 사양을 읽으십시오.

    https://docs.oracle.com/javase/specs/

  • 이전 PowerShell을 사용하여 anonfiles에 파일을 업로드하는 방법
  • 다음 java - EclEmma 및 Eclipse를 사용하여 "범위 데이터가 수집되지 않았습니다"메시지 받기