可以为可以卸载的动态编译代码获得本机性能吗?

时间:2015-07-02 00:08:25

标签: java classloader dynamic-compilation

.Net, it seems你不能

  1. 动态编译代码
  2. 直接调用已编译的代码(即w / o"远程处理",编组等)
  3. 从内存中删除(仅)已编译的代码
  4. 你必须在2.(通过生成调用AppDomain本身的代码)或3.(通过将代码生成一个抛弃的AppDomain)中决定,但你不能同时拥有它们。

    现在我很好奇Java中是否可以这样做。我不太了解ClassLoaders,但似乎在Java中我可以

    1. 将代码动态编译为一个抛弃式类加载器
    2. 直接调用已编译的代码(例如,通过虚拟方法调用预定义的接口),没有任何编组
    3. 删除对编译类和抛弃类加载器的所有引用,以便GC负责删除
    4. 这个假设有效吗?

1 个答案:

答案 0 :(得分:2)

是的,你可以编译/加载一个类代码的类加载器,调用它没有问题。

是的,动态代码将达到“完整性能”。没有区别。但是,新加载的代码将以解释模式启动,并且需要在编译之前预热。

然而,第3点非常棘手。

  • '泄漏'丢弃类加载器非常容易/可能。类加载器保持对它的加载类的引用。每个类都有一个对它的类加载器的引用。每个对象都引用它的类。因此,只要您引用了一个对象或类,该对象或类加载了抛弃类加载器,它和它的加载类就会保持活动状态。 因为很容易引用一个对象,所以'classloader'泄漏很常见。
  • 它取决于GC配置和JVM版本它实际上是GC在加载的类上传递。您可能需要额外的标志才能启用它。与CMS GC' -XX类似:+ CMSClassUnloadingEnabled'。
  • 有一个代码缓存(在OpenJDK / Hotspot中),它保存已编译的代码。如果您在应用程序的所有生命周期内继续加载代码,则可能会超出此缓存。在较旧的JVM中,它刚刚填满,一旦完成,它就会停止编译代码,降低性能,除非你启用了刷新缓存(-XX:+ UseCodeCacheFlushing)。 Afaik在较新版本中默认刷新。仔细检查一下。您可能希望密切关注代码缓存。 (例如通过JMX)