我想以编程方式配置java.util.logging.Logger
。根据{{3}},似乎有可能。
但是这个例子显示了一些错误:
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)
并创建一个新的(默认)之一。
To"解决"这个,我可以在某个地方引用那个特定的记录器,但我认为这不是一个好主意。
那么如何以编程方式定义记录器呢?
答案 0 :(得分:2)
To"解决"这个,我可以在某个地方引用那个特定的记录器,但我认为这不是一个好主意。
在JDK6u18之前的版本中,LogManager保留了对记录器的强引用。在该补丁之后,java.util.logging.Logger.getLogger()方法指向读者持有强大的参考:
注意:LogManager可能只保留对新创建的Logger的弱引用。重要的是要理解,如果没有对Logger的强引用,则可以随时对先前创建的具有给定名称的Logger进行垃圾收集。特别是,这意味着两个背靠背调用,如getLogger(" MyLogger")。log(...)可能会使用名为" MyLogger"的不同Logger对象。如果没有对名为" MyLogger"的记录器的强引用该计划的其他地方。
常用的习惯用法是:
private static final String CLASS_NAME = Foo.class.getName();
private static final Logger logger = Logger.getLogger(CLASS_NAME);
您定义CLASS_NAME
的原因是您将其用于日志跟踪方法或logp
方法
此外,像FindBugs这样的工具会将这种丢失的记录器模式检测为:
LG:由于OpenJDK中的弱引用(LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE),可能导致记录器丢失;
答案 1 :(得分:0)
Javadoc for Logger#getLogger引用了您的问题:
注意:LogManager可能只保留对新创建的Logger的弱引用。重要的是要理解,如果没有对Logger的强引用,则可以随时对先前创建的具有给定名称的Logger进行垃圾收集。特别是,这意味着两个背靠背调用,如getLogger(“MyLogger”)。log(...)可能使用名为“MyLogger”的不同Logger对象,如果没有对名为“MyLogger”的Logger的强引用在该计划中。
反过来Logger#getLogger调用LogManager#addLogger,它的文档也鼓励你持有一个参考:
应用程序应保留自己对Logger对象的引用,以避免被垃圾回收。 LogManager可能只保留弱引用。