Java 可以为可以卸载的动态编译代码获得本机性能吗?
事实上,你不能Java 可以为可以卸载的动态编译代码获得本机性能吗?,java,classloader,dynamic-compilation,Java,Classloader,Dynamic Compilation,事实上,你不能 动态编译代码 直接调用编译后的代码(即不使用“远程处理”、封送等)和 从内存中删除(仅)已编译代码 你必须在两个之间做出决定。(通过将代码生成到调用AppDomain本身)或3。(通过将代码生成一个废弃的AppDomain),但不能两者兼有 现在我很好奇这在Java中是否可行。我对类加载器了解不够,但在Java中我似乎可以 将代码动态编译到一次性类装入器中 直接调用编译后的代码(例如,通过对预定义接口的虚拟方法调用),而不进行任何封送处理 删除对已编译类的所有引用,并丢弃类加载器
这个假设有效吗?是的,您可以编译/加载一个类a代码以外的类装入器,调用它没有问题 是的,动态代码将达到“完全性能”。没有区别。但是,新加载的代码将以解释模式启动,需要在编译之前预热 然而,第3点是错误的。这很棘手
- “泄漏”一次性类装入器非常容易/可能。类装入器保留对其装入的类的引用。每个类都持有对其类加载器的引用。每个对象都是对其类的引用。因此,只要您有一个对对象或类的引用,而该对象或类是用扔掉类装入器装入的,它和它装入的类就会保持活动状态。 因为引用对象非常容易,“classloader”泄漏非常常见
- 这取决于GC配置和JVM版本,它实际上在加载的类上进行GC传递。您可能需要额外的标志来启用它。与CMS GC'-XX:+CMSClassUnloadingEnabled'类似
- 有一个代码缓存(在OpenJDK/Hotspot中),用于保存已编译的代码。如果在应用程序的整个生命周期内一直加载代码,则可能会溢出此缓存。在旧的JVM中,它只是被填满了,一旦填满,它就停止编译代码,性能下降,除非您启用了刷新缓存(-XX:+UseCodeCacheFlushing)。在较新版本中,默认情况下会刷新Afaik。再检查一遍。您可能需要关注代码缓存。(例如通过JMX)