JVM是否会在程序退出时释放所有未被程序员显式关闭的资源?

7

我一直听说在Java中使用的资源必须在使用后关闭,否则这些资源会被耗尽。对于使用极少资源(如1或2个文件读取器/缓冲读取器)的小程序来说,这是否真的值得关注呢?JVM不会跟踪程序使用的资源吗?程序退出后,JVM不会释放所有这些资源吗?如果不是,为什么JVM即使在程序退出后仍然保留这些资源阻塞呢?

4个回答

6

这些资源确实在正常的JVM退出时关闭。然而,您可能不知道您的方法是如何被调用的,并且它可能被另一个程序员外部调用2000次,这些资源将开始堆积。

此外,某些非主流操作系统可能会遇到以下问题:如果JVM异常停止(通过Runtime.getRuntime().halt()或JVM内部发生重要错误/不一致性),则资源可能仍然保持打开状态(由于清理代码未运行),直到重新启动或手动释放为止。即使在主流系统上,套接字也可能保持打开状态多达几分钟。


我知道一个问题,其中一个Java应用程序使用JNI将其链接到DLL。 DLL以某种方式表现不当,以至于System.exit(0)会停止并删除所有线程,但java.exe仍在运行并占用其活动时使用的内存,没有CPU...有时JVM会崩溃。 - GerritCap
如果JVM异常崩溃(或停止),那么一些清理代码(例如关闭流),即使存在,也可能不会被执行,导致资源悬挂在主机操作系统的掌控之外。 - Bimalesh Jha
@GerritCap 是的,无论是否使用JNI,这都是一门不精确的科学。教训是:关闭你的一个bufferedReader。 - nanofarad

3

当进程退出时,JVM也会退出。此时操作系统将释放之前由JVM使用的所有资源,包括内存、文件句柄等。


操作系统将释放JVM之前使用的任何资源。这包括内存、文件句柄等。但是对于非主流/嵌入式操作系统,不能保证此功能。我曾经因此追踪了一个星期。 - nanofarad
一些资源,如打开的套接字,在JVM退出后可能会保持打开状态长达数分钟。 - Bimalesh Jha
@BimaleshJha 不是套接字,而是端口。当进程退出时,大多数操作系统会关闭套接字。TCP 端口 可能会在套接字关闭后保持在 TIME_WAIT 状态几分钟。 - user207421

3
小程序可能会存在资源泄漏的情况,因为操作系统可能会在进程结束后处理这个问题。但这被认为是不可移植的。
更大的问题是,JVM运行的操作系统可能无法知道如何释放在远程机器上分配的资源,或者是否有需要释放的已分配资源。

2

在JVM进程退出后,释放分配给该进程的资源的不是JVM,而是操作系统。


不保证在非主流/嵌入式操作系统上的可用性。 - nanofarad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接