为什么JVM从数据库加载类?

时间:2011-04-29 06:26:29

标签: java sqlite jvm classloader

为什么Java虚拟机没有从数据库加载类(类似于.NET的GAC)?据我了解,目前它必须在类路径上读取和扫描每个JAR的清单,以便找到类文件。不会使用数据库(如SQLite)来提升启动时间吗?

6 个答案:

答案 0 :(得分:7)

这并不是因为没有人将其添加到标准库中。同样为了引导目的(例如,为DB访问加载JDBC驱动程序),仍然需要存在现有机制。

创建一个与数据库对话以检索类位的类加载器并不太难。

答案 1 :(得分:3)

您的基本观点是有效的:Java类加载中存在优化可能性,并且在查找类时显然存在大量重复工作,尤其是那些经常使用的类。 JVM供应商实际上已经在这个领域做了相当多的工作。有关示例,请参阅Oracle's shared data description

我推测使用数据库的开销和复杂性对于实际上简单的缓存和索引问题来说是过度的。

答案 2 :(得分:3)

正在进行非常积极的工作以提高启动时间(这是Project Jigsaw的目标之一,它是JDK 8的一部分)。

但优化并不像“将数据库转储到数据库中”那样简单。这里有几个问题,其中一些是竞争。

GAC有自己的问题,我认为我们都不想复制......

答案 3 :(得分:2)

根据您定义“数据库”的方式,IBM(shared classes)和Oracle(shared data)已经拥有加速启动和减少内存占用的技术。

类加载时间实际上非常小(逐个类),所以在这种方式中添加类似数据库的东西不会以一种好的方式实际改变你的性能,特别是如果你必须在连线(而不是简单地读取本地文件系统jar条目)。今天的所有JVM都在类加载路径下进行了高度优化,添加SQL肯定无法提高性能。 (分布式存储库的灵活性等等。是一个不同的问题,我看到那里有优势。)

答案 4 :(得分:1)

您可以将nexus服务器用作库的maven存储库,并将它们加载到OSGi容器中。这允许您构建/部署/加载/卸载整个库而无需直接触及jar或类。但是,它会将磁盘库的本地副本放在磁盘上以提高性能,并且不允许您管理各个类。

我会发现很难相信在套接字连接上加载clases比直接从磁盘加载压缩文件要快。 (正如maven / OSGi所做的那样)尤其是一旦文件在缓存中。加载类所花费的大部分时间都是在静态块中执行的代码中,后来编译代码,数据库都不会帮助您。

我很想看到性能比较。数据库类存储库如何处理版本?回滚一个版本的库或具有相互依赖性的类组是多么容易/可靠?

答案 5 :(得分:1)

您可以创建一个索引jar,它将告诉运行时哪个类在哪个jar中。为此,您需要使用应用程序主jar并确保在Manifest中正确设置Class-Path属性。然后运行“jar -i MyMainJar.jar”来创建索引。

如果你没有主jar,你可以创建一个只包含一个Manifest,其中Class-Path属性设置和索引。如果先加载这个jar,ClassLoader将使用索引并更快地查找类。