通过编程配置记录器



我想通过编程方式配置我的 java.util.logging.Logger。根据Oracle文档,似乎有可能。

但是,此示例在这里显示出什么问题:

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)留下创建新的(默认(一个。

要"解决"这个问题,我可以在某个地方提及该特定的记录器,但我认为这不是一个好主意。

那么我如何以编程方式定义记录器?

要"解决"这个问题,我可以在某个地方提及该特定的记录器,但我认为这不是一个好主意。

在JDK6U18之前发行版中,Logmanager对Logger有很强的引用。在该补丁之后,Java.util.logging.logger.getLogger((方法将读者指向有很强的参考:

注意:Logmanager只能保留对新创建的Logger的弱参考。重要的是要了解,如果没有强烈的对记录器的参考,则可以随时收集具有给定名称的先前创建的记录器。特别是,这意味着两个背对背调用,例如getLogger(" mylogger"(。log(...(可能会使用名为" mylogger"的不同的记录器对象,如果对其他位置的名为" mylogger"的logger没有强烈的引用在程序中。

一个常见的成语是使用:

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_to_weak_reference(

logger#getlogger引用您的问题:

注意:Logmanager只能保留对新创建的Logger的弱参考。重要的是要了解,如果没有强烈的对记录器的参考,则可以随时收集具有给定名称的先前创建的记录器。特别是,这意味着两个背对背调用,例如getLogger(" mylogger"(。log(...(可能会使用名为" mylogger"的不同的记录器对象,如果对其他位置的名为" mylogger"的logger没有强烈的引用在程序中。

反过来logger#getlogger调用logmanager#addlogger及其文档也鼓励您保存参考:

https://docs.oracle.com/javase/7/docs/api/java/java/util/logging/logmanager.html#addlogger(java.util.util.util.logging.logger.logger;

该应用程序应保留自己对Logger对象的引用,以避免收集垃圾。logmanager只能保留弱参考。

最新更新