我正在开发一个富客户端应用程序,现在我将其迁移到在 NetBeans RCP
中运行。到目前为止一切都很顺利。
最近,我构建了第一个版本,发现启动花费了几乎一分钟而不是 10 秒。从 IDE
中启动时,一切都像以前一样快。
对我看到的所有内容进行分析后,加载数千个 XML
文件(JPA
的配置)需要比以前多 10-20 倍的时间。我添加了一些 printlns
并发现加载大约需要 50 毫秒,而不是像之前每个文件的 <1 毫秒。我发现这个问题只发生在签名的 jar 文件上。当我使用未签名的 jar 启动完全相同的应用程序时,时间又回到了 10 秒。当我在没有 NetBeans
与签名 jar 集成的情况下启动应用程序时,也只需要 10 秒。
从代码点来看,该资源的加载根本没有改变。在运行时,差异很可能在于类加载。 NetBeans 提供 class loader hierachy 。我尝试将其中任何一个设置为上下文类加载器,但这对性能没有影响。我还使用内存分析器进行了检查,class of classloader无论是否集成 NetBeans,所使用的内容都是相同的
我尝试过分析,但这很困惑。探查器(JProfiler
)不显示类加载的堆栈,仅显示资源已加载。即使是java的“-verbose选项”也仅显示资源已加载。
在不知道确切的类加载算法的情况下,我假设它由以下部分组成。但对于我签名的应用程序来说,这些部分应该是相同的,无论是否集成 NetBeans。
- finding the resource in the classpath
- loading the resource
- verifiing
- test checksum
- validate certificate with CA (maybe http request, but only once (hopefully))
您知道该行为的原因是什么吗?
集成信息:
旧应用程序使用一个 JFrame
和多个 JInternalFrames
来处理多个窗口。当我们开始使用 NetBeans 时,它会捕获旧的 JFrame
,而不是在 JInternalFrame
中显示我们的内容,而是在动态创建的顶级组件中显示它。集成的主要原因是 NetBeans 中的窗口管理(停靠、 float ...)。
最佳答案
我自己找到的。如果有人对此感兴趣的话,这就是答案。
启动时,NetBeans
调用以下方法来禁用所有缓存。这会导致每次资源加载时重新加载 jar 文件。对于签名的 jar,这还包括对 jar 的完整验证。
java.net.URLConnection.setDefaultUseCaches(boolean)
我在 JPA
配置期间重新启用了此功能,并且工作正常。我不太确定 NetBeans
为什么这样做,但我猜这是关于模块的在线更新。
关于java - Netbeans 类加载器在使用签名 jar 加载资源时速度缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27860598/