FileHandler的关闭将删除“
lck”文件。如果锁定文件在低于更新40(java.util.logging)的JDK8版本中根本存在,则FileHandler将旋转。根据OpenJDK的讨论,如果当前进程无法锁定lck文件,则决定始终旋转。给出的原因是,当存在锁定文件时,旋转总是更安全。因此,如果您在混合JDK版本中使用旋转模式,这将变得非常讨厌,因为JDK7版本将重用锁,而JDK8版本将保留并旋转。您正在使用测试用例做什么。
如果我从工作目录中 清除所有日志和lck文件 ,然后使用JDK8 运行:
public static void main(String[] args) throws IOException { System.out.println(System.getProperty("java.runtime.version")); new FileHandler("./test_%u.log", 10000, 100, true).close();}
我总是看到一个名为“ test_0.log.0”的文件。使用JDK7我得到相同的结果。
最重要的是,您必须确保关闭FileHandlers。如果从未对其进行过垃圾收集或从记录器树中删除,则LogManager将关闭您的FileHandler。否则,您必须关闭它。解决此问题之后,请清除所有锁定文件,然后再运行新的修补代码。然后请注意,如果JVM进程崩溃或被杀死,锁定文件将不会被删除。如果关闭时遇到I
/ O错误,则不会删除锁定文件。当下一个进程开始时,FileHandler将旋转。
如您所指出的,如果上述情况超过100次运行,就有可能用完JDK8上的所有锁定文件。一个简单的测试是两次运行以下代码,而不删除log和lck文件:
public static void main(String[] args) throws Exception { System.out.println(System.getProperty("java.runtime.version")); ReferenceQueue<FileHandler> q = new ReferenceQueue<>(); for (int i=0; i<100; i++) { WeakReference<FileHandler> h = new WeakReference<>( new FileHandler("./test_%u.log", 10000, 2, true), q); while (q.poll() != h) { System.runFinalization(); System.gc(); System.runFinalization(); Thread.yield(); } }}
但是,如果正确修复了JDK-6774110,则上述测试用例将无法正常工作。可以在OpenJDK站点上的RFR下追踪此问题:8048020-java.util.logging.FileHandler和FileHandler webrev
上的回归。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)