4

我最近一直在玩开发、测试和删除构建目录 - 并注意到这导致的错误比我想象的要少。

我很好奇是否有人可以详细解释当我们在 Java 应用程序运行时删除类文件目录时会发生什么。我假设在某些时候,这不会影响应用程序(即因为所有操作都将作为字节码推入堆栈)。但是我们什么时候会到达这个不归路?JVM 是否会在某个时候缓存或完全拥有正在运行的应用程序中的所有类,从而使它们的初始位置(即,当我们最初开始运行 java 进程时的 .class 文件的位置)不再重要?

4

2 回答 2

2

首次访问时需要该类文件。它通常不被缓存,而是 ClassLoader 提取它需要的所有信息并且不会.class再次读取。

通常最好的做法是写入一个新目录,如果最后一个版本仍然存在(或者如果您希望能够回滚到该版本),则在创建新版本时

在程序运行时删除/编辑程序会导致 shell 脚本和 C 程序出现问题,因此它在 Java 中不能很好地运行也就不足为奇了。

正如@Louis Wasserman 指出的那样,OP 表示它的效果比预期的要好。恕我直言,这将取决于应用程序。如果加载了所有需要的类,您可以将它们全部删除。启动后很长时间才加载类的应用程序不会以这种方式运行。

于 2012-04-27T16:42:11.810 回答
1

如今,大多数 JVM 以“按需”方式加载类,因此当您启动 Java 程序时,JVM 根据活动引用根据需要读入 .class 文件。(它比这更复杂,但为了简单起见,假设它接近现实。)一旦加载,磁盘上的字节不再需要,因为它们已被转换为 JVM 内部表示并保存在内存中。实际上,一旦加载了类,就不再需要将它们放在磁盘上(假设您再也不会从头开始运行相同的程序!)。

但是,有一个很大的问题......很可能并非程序中的所有类实际上都是在平均运行中加载的。想象一个只在奇怪的情况下才需要的错误类。正常执行不会加载它,因此,如果您在程序“正常”运行后简单地从文件系统中删除所有内容,然后遇到需要加载类的错误条件,那么 JVM 将失败两次-不好的方式 - 而不是抛出预期的异常(将通过您的 catch 块正常处理)会发生更严重的错误,从而使您的逻辑脱轨。

可以“预加载”所有类,但它有点小技巧,通常通过诸如保留应用程序中所有类的列表并为每个类执行“Class.forName()”等方法来完成。请参阅这篇 SO文章,了解人们出于性能原因如何做到这一点。

于 2012-04-29T17:49:30.623 回答