如何在 jar 文件上远程执行方法
Posted
技术标签:
【中文标题】如何在 jar 文件上远程执行方法【英文标题】:How to execute a method remotely on a jar file 【发布时间】: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 可以纠正我。 【参考方案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 文件使用单独的类加载器,那么垃圾收集器就会释放内存 需要时,假设您不保留不需要的引用。 那是完美的。感谢您的宝贵时间!以上是关于如何在 jar 文件上远程执行方法的主要内容,如果未能解决你的问题,请参考以下文章