[java] StackTrace가없는 Java의 NullPointerException

Java 코드 catch의 인스턴스를 가지고 NullPointerException있지만 StackTrace (기본적으로 호출을 끝내는)를 기록하려고 Throwable.printStackTrace()하면 다음과 같이됩니다.

java.lang.NullPointerException

다른 사람이 이것을 보았습니까? “java null pointer empty stack trace”에 대한 인터넷 검색을 시도했지만 이와 같은 것을 발견하지 못했습니다.



답변

많은 최적화를 수행하는 HotSpot JVM (원래 Sun Microsystems에서 나중에 Oracle에서 구입 한 OpenJDK의 일부)을 사용하고있을 것입니다. 스택 추적을 되돌리려면 옵션 -XX:-OmitStackTraceInFastThrow을 JVM 에 전달해야합니다 .

최적화는 예외 (일반적으로 NullPointerException)가 처음 발생할 때 전체 스택 추적이 인쇄되고 JVM이 스택 추적 (또는 코드 위치)을 기억한다는 것입니다. 이러한 예외가 자주 발생하면 더 나은 성능을 달성하고 동일한 스택 추적으로 로그를 넘치지 않도록 스택 추적이 더 이상 인쇄되지 않습니다.

이것이 HotSpot JVM에서 어떻게 구현되는지 보려면 , 사본을 잡고 전역 변수를 검색하십시오 OmitStackTraceInFastThrow. 지난 코드 (2019 년)를 살펴보면 graphKit.cpp 파일에 있었습니다 .


답변

주석에서 언급했듯이 log4j를 사용하고 있습니다. 내가 쓴 곳을 (무심코) 발견했다

LOG.error(exc);

전형적인 대신

LOG.error("Some informative message", e);

게으름이나 아마도 그것에 대해 생각하지 않고. 불행한 점은 예상대로 동작하지 않는다는 것입니다. 로거 API는 실제로 Object가 문자열이 아닌 첫 번째 인수로 사용 된 다음 인수에서 toString ()을 호출합니다. 따라서 멋진 스택 추적을 얻는 대신 toString을 인쇄하면 NPE의 경우 쓸모가 없습니다.

아마도 이것이 당신이 겪고있는 것입니까?


답변

우리는 과거에도 이와 같은 행동을 보았습니다. 미친듯한 이유로, NullPointerException이 코드의 동일한 장소에서 여러 번 발생하면 잠시 후에 사용 후 Log.error(String, Throwable)전체 스택 추적을 포함 하여 중지됩니다.

로그를 다시 살펴보십시오. 범인을 찾을 수 있습니다.

편집 : 이 버그는 관련이있는 것으로 보이지만 오래 전에 수정되었습니다. 아마 원인이 아닙니다.


답변

설명은 다음과 같습니다. 핫스팟으로 인해 예외가 프로덕션에서 스택 추적을 잃어 버렸습니다.

Mac OS X에서 테스트했습니다.

  • 자바 버전 “1.6.0_26”
  • Java (TM) SE 런타임 환경 (빌드 1.6.0_26-b03-383-11A511)
  • Java HotSpot ™ 64 비트 서버 VM (빌드 20.1-b02-383, 혼합 모드)

    Object string = "abcd";
    int i = 0;
    while (i < 12289) {
        i++;
        try {
            Integer a = (Integer) string;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

이 특정 코드 조각의 경우 12288 반복 (+ 빈도?)이 JVM이 사전 할당 예외를 사용하기로 결정한 한계 인 것 같습니다 …


답변

exception.toString StackTrace를 제공하지 않고 반환 만합니다.

이것에 대한 간단한 설명. 결과는 다음과 같습니다.

* the name of the class of this object
* ": " (a colon and a space)
* the result of invoking this object's getLocalizedMessage() method

사용하여 exception.printStackTrace출력 스택 트레이스 대신.


답변

다른 제안-Eclipse를 사용하는 경우 NullPointerException 자체에 중단 점을 설정할 수 있습니다 (디버그 관점에서 “Breakpoints”탭으로 이동하여!가있는 작은 아이콘을 클릭하십시오)

“catch”및 “uncaught”옵션을 모두 확인하십시오. 이제 NPE를 트리거하면 즉시 중단 점이 발생하며 정확히 처리 된 방법과 스택 추적이 발생하지 않는 이유를 단계별로 확인할 수 있습니다.


답변

toString()예외 이름과 선택적 메시지 만 반환합니다. 나는 전화를 제안합니다

exception.printStackTrace()

메시지를 덤프하거나 처참한 세부 정보가 필요한 경우 :

 StackTraceElement[] trace = exception.getStackTrace()