JVM程序的理论方面:类文件和内部化以及执行状态

时间:2012-04-27 16:34:50

标签: java caching binary jvm

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

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

2 个答案:

答案 0 :(得分:2)

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

通常,最佳做法是在创建新版本时写入新目录(如果上一版本仍处于活动状态(或者如果您希望能够回滚到该版本))

在程序运行时删除/编辑程序会导致shell脚本和C程序出现问题,所以它不应该太令人惊讶,因为它在Java中不能很好地工作。

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

答案 1 :(得分:1)

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

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

可以“预加载”所有类,但它有点像黑客,通常用kludges完成,例如保存应用程序中所有类的列表,并为每个类执行“Class.forName()”。请参阅此SO article了解人们出于性能原因这样做的原因。