CodeQL 文档

危险的 runFinalizersOnExit

ID: java/run-finalizers-on-exit
Kind: problem
Security severity: 
Severity: error
Precision: medium
Tags:
   - reliability
   - maintainability
Query suites:
   - java-security-and-quality.qls

单击以在 CodeQL 存储库中查看查询

避免调用 System.runFinalizersOnExitRuntime.runFinalizersOnExit,它们被认为是危险的方法。

Java Development Kit 文档中关于 System.runFinalizersOnExit 的说明

此方法本质上不安全。它可能导致对活动对象调用终结器,而其他线程同时操作这些对象,从而导致不稳定行为或死锁。

对象终结器通常仅在垃圾回收器即将回收对象时调用。使用 runFinalizersOnExit 会设置一个 Java 虚拟机范围的标志,在运行时退出之前对所有带有 finalize 方法的对象执行终结器。这将要求所有带有终结器的对象防止在对象仍在使用时调用 finalize,这对大多数应用程序来说不切实际。

建议

确保代码不依赖于终结器的执行。如果代码依赖于 Java 虚拟机的垃圾回收行为,则无法保证终结器将及时执行,甚至根本不会执行。如果终结器用于处置有限的系统资源(例如文件句柄),这可能会成为问题。

使用显式 dispose 方法(而不是终结器)在 finally 块中,以确保释放对象的资源。

示例

以下示例显示了一个调用 runFinalizersOnExit 的程序,不建议这样做。

void main() {
	// ...
	// BAD: Call to 'runFinalizersOnExit' forces execution of all finalizers on termination of 
	// the runtime, which can cause live objects to transition to an invalid state.
	// Avoid using this method (and finalizers in general).
	System.runFinalizersOnExit(true);
	// ...
}

以下示例显示了建议的方法:一个在 finally 块中调用 dispose 方法的程序。

// Instead of using finalizers, define explicit termination methods 
// and call them in 'finally' blocks.
class LocalCache {
	private Collection<File> cacheFiles = ...;
	
	// Explicit method to close all cacheFiles
	public void dispose() {
		for (File cacheFile : cacheFiles) {
			disposeCacheFile(cacheFile);
		}
	}
}

void main() {
	LocalCache cache = new LocalCache();
	try {
		// Use the cache
	} finally {
		// Call the termination method in a 'finally' block, to ensure that
		// the cache's resources are freed. 
		cache.dispose();
	}
}

参考

  • ©2025GitHub, Inc.
  • 条款
  • 隐私