【问题标题】:How to execute a method remotely on a jar file如何在 jar 文件上远程执行方法
【发布时间】:2011-05-23 16:49:07
【问题描述】:

我有一个应用程序,其目的是在跨文件系统的许多不同 jar 文件中调用同一类中的相同特定方法并接收结果。所以我可以保证某个类和方法会存在于一个jar文件中。

我知道每个 jar 文件的位置。我很容易通过反射来实例化类并以这种方式调用方法。

我的问题是我有很多这些 jar 文件。如果我使用上述方法调用每个 jar,我担心我的应用程序的内存消耗会急剧增加,因为我必须为每次调用加载整个 jar 文件。

除了反射之外,我还有什么方法可以调用这些 jars 文件?系统调用不起作用,因为我需要接收一个值。

非常感谢...

【问题讨论】:

  • 出于兴趣,如何在代码中从不同的 jar 文件中加载同一个类?
  • 您是否考虑过使用单独的类加载器并在最后处理它?我认为这就是容器进行 .jar 管理 (Tomcat) 的方式。
  • @DaveHowes - 我只是创建了一个本地 URLClassloader,其中包含我感兴趣的 jar 文件的 URL。然后我使用 Class.ForName() 等。
  • @Rekin - 是的,我使用本地 URLClassloader,它在调用完成后超出范围。然而此时,我感兴趣的 jar 已经加载完毕。它还会留在记忆中吗?
  • @Belltower: AFAIK 类定义直接进入 perm gen 空间,这很少被扫除,但有时仍然如此。当没有任何东西引用它们时,就没有理由保留它们。也许 Jochen 可以纠正我。

标签: java reflection jar execution


【解决方案1】:

您可能会遇到烫发空间的问题,但可以使用-XX:MaxPermSize= 增加此问题 参数。

确保您为每个 JAR 文件使用单独的 URLClassLoader,并且不要保留它们以便获取 GCd。 通过新的 URLClassLoader 加载 JAR 文件,然后使用 Class.forName() 加载。

祝你好运!

【讨论】:

  • 是的,这就是我目前的做法。我创建了一个本地 URLClassLoader,其中包含我感兴趣的 jar 文件的路径。然后我使用 class.FoName() 等。不过,一旦通过 ClassLoader 加载 jar 文件,它是否会保留在内存中? ClassLoader 已经被 GC 处理了吗?
  • 曾经有关于打开文件和 URLClassLoaders 的问题。如果您有幸使用早期的 Java 7 版本,它在 URLClassLoaders 上有一个新的 close() 方法。
  • 你还要考虑JVM中的缓存机制。我想没有办法在 URLClassLoader 缓存中禁用缓存。
【解决方案2】:

我会做这样的伪代码:

foreach jf : myJarFiles
  jcl = new JarClassLoader(jf);
  Class.forName(myClassName);
  m = MyClass.getMethod(...);
  m.invoke(...);

【讨论】:

  • 是的,我就是这样做的。它只是我担心的罐子管理方面。一旦本地类加载器超出范围,我希望将已加载到内存中的 jar 文件释放。否则我担心重复调用加载 jar 文件后的内存大小。
  • @belltower:请注意,JVM 的内存使用量会随着您加载每个 JAR 文件而增加,但只要您为每个 JAR 文件使用单独的类加载器,那么垃圾收集器就会释放内存 需要时,假设您不保留不需要的引用。
  • 那是完美的。感谢您的宝贵时间!
猜你喜欢
  • 2023-03-21
  • 2016-02-07
  • 2016-06-26
  • 1970-01-01
  • 2014-12-31
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多