2017-04-21 2 views
3

프로그래밍 방식으로 java.util.logging.Logger을 구성하고 싶습니다. Oracle Docs에 따르면, 가능합니다.프로그래밍 방식으로 로거 구성

public static void main(String[] args) { 
    Logger logger = Logger.getLogger("org.acme.project"); 
    logger.setLevel(Level.SEVERE); 
    logger = null; 

    System.gc(); 

    logger = Logger.getLogger("org.acme.project"); 
    logger.warning("You shouldn't see this warning!"); 
    logger.severe("But this error!"); 
} 

코드를 실행하면 두 메시지가 표시됩니다

그러나이 예는 뭔가 잘못 여기 보여줍니다. 그러나 logger = null; 또는 System.gc();을 제거하면 가비지 수집기가 Logger.getLogger(String)을 떠나는 구성 된 로거를 제거하고 새로운 (기본값) 것을 생성한다는 것을 증명하는 정확한 두 번째 것을 볼 수 있습니다.

"해결"하려면 특정 로거에 대한 참조를 보관할 수는 있지만 좋은 생각이라고 생각하지 않습니다.

그럼 프로그래밍 방식으로 로거를 정의하려면 어떻게해야합니까?

답변

2

"해결"하려면 특정 로거에 대한 참조를 저장할 수 있지만 좋은 생각은 아닙니다.

JDK6u18 이전의 릴리스에서 LogManager는 로거에 대한 강력한 참조를 보유했습니다. 이 패치 이후에 java.util.logging.Logger.getLogger() 메서드는 독자가 강력한 참조를 유지하도록 지시합니다.

참고 : LogManager는 새로 생성 된 로거에 대한 약한 참조 만 유지할 수 있습니다. 로거에 대한 강한 참조가없는 경우, 지정된 이름의 이전에 작성된 Logger가 언제라도 가베지 수집 될 가능성이있는 것을 이해하는 것이 중요합니다. 특히 이것은 getLogger ("MyLogger") .log (...)와 같은 두 개의 back-to-back 호출은 "MyLogger"라는 다른 기록 장치에 대한 강력한 참조가없는 경우 "MyLogger"라는 다른 Logger 객체를 사용할 수 있음을 의미합니다 프로그램에서. 너무 로그 추적 방법 또는 logp 방법 또한

, 툴을 사용하는 것이 오

private static final String CLASS_NAME = Foo.class.getName(); 
private static final Logger logger = Logger.getLogger(CLASS_NAME); 

이유를 당신이 CLASS_NAME을 정의

일반적인 관용구 사용하는 것입니다 FindBugs와 같이 손실 된 로거 패턴을 다음과 같이 감지합니다.

LG : 취약한 참조로 인해 로거가 변경 될 수 있습니다. 오픈 JDK의 NCE (LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE는)

+0

나는 왜 OP의 문제를 겪어 본 적이 없는지 깨닫기 위해 잠시 나갔다. 이것은 확실히 당신이 사용해야하는 관용구입니다. – Qix

0

로거 # getLogger를위한 Javadoc가 문제를 참조 :

https://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#getLogger%28java.lang.String%29

참고 : LogManager의는 새로 만든 로거에 약한 참조를 보유 할 수 있습니다. 로거에 대한 강한 참조가없는 경우, 지정된 이름의 이전에 작성된 Logger가 언제라도 가베지 수집 될 가능성이있는 것을 이해하는 것이 중요합니다. 특히 이것은 getLogger ("MyLogger") .log (...)와 같은 두 개의 back-to-back 호출은 "MyLogger"라는 다른 기록 장치에 대한 강력한 참조가없는 경우 "MyLogger"라는 다른 Logger 객체를 사용할 수 있음을 의미합니다 프로그램에서.차례 로거 # getLogger에서

은 LogManager의 # addLogger를 호출하고 해당 설명서도 참조를 개최 할 것을 권장합니다 :

https://docs.oracle.com/javase/7/docs/api/java/util/logging/LogManager.html#addLogger%28java.util.logging.Logger%29

방지하기 위해 Logger 오브젝트에 대한 스스로의 참조를 유지해야하는 응용 프로그램 쓰레기 수거. LogManager는 약한 참조만을 유지할 수 있습니다.

관련 문제