如何预加载整个jar文件

3
我希望能在启动时预加载所有类和资源的整个jar文件,以便后续Java程序执行不需要访问硬盘。您推荐哪种方法?
更新:
该jar已经使用proguard进行了优化,它检测到某些死代码并将其从输出中删除。因此,加载永远不会被使用的类不是问题。

1
这个回答解决了你的问题吗?在jar启动时预加载java类/库? - Dave Jarvis
2个回答

2
推荐的方式是不这样做,这会带来太多问题。
问题在于(一般而言),你无法保证已经加载了所有需要加载的类...除非你对你的代码和它所依赖的库代码(包括Java SE库)进行详细分析。而由于某些组件可能会进行动态类加载,这种分析是很困难的。
理论上,你可以遍历类加载器树的命名空间并加载每个类。但你最终会加载大量永远不会被应用程序使用的代码。
跳出思维定势...
你可以将JAR文件读入内存,然后使用自定义类加载器从内存副本中加载。但是这样会有一个问题。标准的JarFileZipFile API不能从流或内存缓冲区中读取。因此,你需要使用JarInputStream来迭代JAR的条目,读取相应的内容,并将其缓存在内存中。
当然,如果加载应用程序类触发从标准库中加载类,则你的应用程序需要从磁盘读取。(除非你缓存核心库JAR和ZIP文件。)
然后就有了棘手的问题:某些类依赖于动态加载的本地库,而该依赖关系在类加载时无法解析。那些本地库也会在磁盘上。
此外,应用程序JAR文件中可能还有其他资源(图像、属性文件等),这些资源可能会被应用程序动态读取。

JAR 中还有许多其他资源。它们是预加载的主要原因。 - ayvango
@ayvango - 是的,我知道。请看我的回答。但是你问的是预加载>>所有<<内容,以便您不必再次引用硬盘驱动器(完全不需要)。我解释了您可以做什么,以及将所有内容预加载到不需要从硬盘驱动器读取的程度是不切实际的。 - Stephen C
有些信息驻留在硬盘中,调用它们是可以的。但是有一个JAR文件只是暂时存在于这里。所以我想预先载入并忘记。 - ayvango
所以...只需像我描述的那样将JAR加载到内存中即可。另请参阅:https://dev59.com/kmjWa4cB1Zd3GeqPmwkQ...该链接建议将JAR复制到“RAM磁盘”文件系统中。 - Stephen C

-1

你可以看一下Reflections库。

然而,你应该考虑permgen大小和内存利用率,可能会导致硬盘使用情况变得更糟。

此外,请记住JRE/JDK类,它们不在应用程序的类编译和打包的jar中出现。


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