Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Logger.getLogger的行为不一致,这取决于变量是否为内联变量_Java_Logging - Fatal编程技术网

Java Logger.getLogger的行为不一致,这取决于变量是否为内联变量

Java Logger.getLogger的行为不一致,这取决于变量是否为内联变量,java,logging,Java,Logging,稍后编辑:(为什么我认为情况与此不同) 所有操作都在一个实例方法中完成,输入和输出,每个文件处理一次。我提取的本地字段(而不是内联字段)不在其他任何地方使用,因此GC在迭代后会清除它 -- 在标准J2SE应用程序中(mainmethod从Eclipse运行),当使用ApachePDFBox和pdf2dom进行pdf到html的转换时,我想清除一些不需要的信息日志条目 意外情况: 这段代码每次都可以正常工作: Logger logger = Logger.getLogger("org.ma

稍后编辑:(为什么我认为情况与此不同)

所有操作都在一个实例方法中完成,输入和输出,每个文件处理一次。我提取的本地字段(而不是内联字段)不在其他任何地方使用,因此GC在迭代后会清除它

--

在标准J2SE应用程序中(
main
method从Eclipse运行),当使用ApachePDFBox和pdf2dom进行pdf到html的转换时,我想清除一些不需要的信息日志条目

意外情况:

这段代码每次都可以正常工作:

    Logger logger = Logger.getLogger("org.mabb.fontverter.opentype.TtfInstructions.TtfInstructionParser");
    logger.setLevel(Level.WARNING);
但是,如果我内联
logger
变量,它将开始意外地运行:

Logger.getLogger("org.mabb.fontverter.opentype.TtfInstructions.TtfInstructionParser").setLevel(Level.WARNING);
在第二种情况下,记录器上的更改仅在允许经过一个小的时间间隔后生效:

  • 如果我调试并花几秒钟检查线路
  • 或者,如果我处理多个pdf文件,这意味着整个执行过程需要稍长的时间
对此有何解释


谢谢。

简而言之,添加局部引用可以延长对象的寿命

Oracle的Vladimir Ivanov在OpenJDK核心libs邮件列表中解释了这一点:

HotSpot中的JIT编译器积极地进行修剪,但确实如此 这是基于方法的(而不是基于优化的IR)。 因此,任何对本地应用程序的使用都会扩展其活动范围,即使这种使用是 在生成的代码中消除。这意味着本地的oop将继续存在 在生成的代码和所有安全点(在生成的 代码)直到最后一次使用(字节码级别)将枚举它所在的本地 坚持住

如果只支持GC安全点,那么JIT仍然可以删减 oop映射中未使用的局部变量,但HotSpot没有这些局部变量以及所有局部变量 生成的代码中的安全点保持完整的JVM状态,因此总是 可以在其中任何一个进行去优化(然后运行到代码中 这将在生成的代码中消除)

如果在方法结束之前没有安全点,那么什么都不会发生 使对象保持活动状态。但是GC没有办法收集它,因为 地面军事系统依靠安全点来标记线程堆栈。(这就是我提到的原因 GC仅适用于前面的安全点。)

因此,只要本地ref延长了logger对象的生命周期,使得
logger.getLogger
返回由本地var创建和保存的记录器,它就可以正常工作


对于日志记录,不要使用方法本地引用。而是将对记录器的引用保留在a中,最好在记录器开始发布记录之前设置一次级别。

我只是猜测,但这可能与垃圾收集以及如何保留对
记录器的引用有关。您正在使用哪个日志库?可能有更好的方法来过滤显示的日志。我使用的第三方库使用的是slf4j。按照相同的方法,执行实际工作的代码(从那些库(pdfbox、pdf2dom)调用功能就在“Logger.getLogger”行的正下方。对每个pdf文件调用此方法。由于日志配置更改在第二次迭代时生效,我猜GC没有清除日志记录程序……slf4j只是许多不同日志库的接口(实现可以类似于logback或log4j)。您在依赖项中使用的是哪种实现?我不知道如何回答这个问题;创建不需要的日志项的库是“pdf2dom”;在检查了maven依赖项之后,我发现它还带来了SLF4JAPI,但没有其他与日志相关的功能。如果我调试代码并检查上面两行代码中的
logger
变量,则它是一个简单的
java.util.logging.logger
对象。情况不同。在我的例子中,所有的事情都是在一个非静态方法的主体中完成的。如果我执行了多个文件,那么我将再次输入该方法。我创建的“logger”局部变量没有在其他任何地方使用,因此没有任何东西可以阻止GC清除它。。。