使用不同的java应用程序导出选项的奇怪行为

Suv*_*ica 6 java eclipse jvm jar maven

我有java服务器应用程序,它使用很多库(netty,guava等).我总是将此应用程序导出为单个.jar.当我在Eclipse中运行应用程序时,我没有任何问题.但是,如果我在控制台(Windows或Ubuntu,无关紧要)启动应用程序,我有一个奇怪的问题:通过套接字的所有连接进程持续太长时间.例如,通过HttpAsync或其他人(rabbitmq连接等)的简单http连接持续1-2分钟.但连接完成后,数据发送/接收速度很快.我无法弄清楚是什么问题.如前所述,我使用Eclipse进行开发.

如您所知,您可以导出项目3方式(在Eclipse中):

  1. 将所需的库提取到JAR中.
  2. 将所需的库打包到JAR中.
  3. 将所需的库复制到JAR旁边的子文件夹中.

所以,当我使用2选项时,我遇到了问题.当我切换到3d选项(main .jar附近的文件夹中的所有.jars)时,问题就解决了.

一般来说,2和3选项之间没有太大的区别(2个所有.jars只在一个jar内).我认为这是从jar开始在执行时加载新类所需的额外时间的原因.但问题不仅发生在开始,而且发生在所有新连接上.

有人可以解释这种行为吗?

UPD: Eclipse Luna.无论我使用什么操作系统(Windows,或Ubuntu),甚至无关紧要jvm(尝试使用不同的Oracle jdk,甚至尝试打开jdk).

hag*_*wal 4

这一切都讨论了打包到 JAR 与提取到 JAR 时的性能差异以及从 Eclipse 运行与从控制台运行时的性能差异。

打包到 JAR 与提取到 JAR 时的性能差异:

将所需的库提取到 JAR 中:

它的作用:
在此选项中,Eclipse 将从引用的 JAR 中提取所有类并打包到生成的 JAR 中。

如果打开 JAR,您会发现没有打包引用的 JAR,但引用的 JAR 的所有类都按照包结构排列,然后打包在根级别的 JAR 中。与“将所需的库打包到 jar 文件中”相比,这带来了性能上的关键差异,“将所需的库打包到 jar 文件中”还需要运行时解析和在内存中加载 JAR 等成本。

当通过 Eclipse 导出为 JAR 时,如果考虑性能,这是最佳选择。这也是可扩展的选项,因为您可以发送此 JAR

MANIFEST.MF 该文件中要注意的主要内容是您的主类。当您运行 JAR 时,您将直接运行您需要的类。

Main-Class: com.my.jar.TestSSL
Run Code Online (Sandbox Code Playgroud)


将所需的库打包到 JAR 中:

它的作用:
在此选项中 Eclipse 将:

  • 将所有引用的 JAR 打包到生成的 JAR 中。
  • 通过使用Eclipse的JAR加载机制org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader,你还可以看到org.eclipse.jdt.internal.jarinjarloaderpackage到你生成的JAR中,这个包就在生成的JAR的根目录下。

当然,这是当您选择此选项时产生的额外成本,因为当您运行 JAR 时,不是您的主类被执行,而是JarRsrcLoader将被执行,它将加载您的主类和其他库,并且所有引用的库都是包装好的。请参阅下面的 MANIFEST.MF 部分

MANIFEST.MF 该文件中要注意的主要内容是您的主类。当您运行 JAR 时,JarRsrcLoader将运行并执行进一步的工作。

Rsrc-Main-Class: com.cgi.tmi.TestSSL
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Run Code Online (Sandbox Code Playgroud)


现在,对于最后一个 Eclipse 导出选项 - “将所需的库复制到 JAR 旁边的子文件夹中”,我认为这不是一个值得考虑的可伸缩解决方案,因为这会强加文件系统依赖性,所以我会说不要这样做。

从 Eclipse 运行与从控制台运行时的性能差异:

当您从 Eclipse 运行应用程序时,它会很安静,类似于第一个导出选项,其中 Eclipse 不需要在运行时解析和加载 JAR。
然而,这是一个非常琐碎的问题,关键是考虑 Eclipse JAR 导出选项 1 和选项 2。


最后的话:

  • 使用“将所需库提取到 JAR 中”来导出 JAR,您将看到显着的性能提升。
    • 当您从控制台运行时,套接字连接持续很长时间的可能性极小,因为 JVM 运行代码,那么当从 Eclipse 和控制台运行时,它会具有相同或非常相似的性能(在这两种情况下考虑相同的 Java 版本)。您可能会因为打包的 JAR 性能而感到不舒服。尝试提取 JAR,应该没问题。
  • 另外,请考虑您正在进行的日志记录量。运行时,根据配置,Eclipse 可能会屏蔽大量日志记录,从而节省您的 I/O 时间。
  • 请务必了解如何从 JAR 类路径 访问类,这就像从 JAR 引用类时的额外计算成本。