如何在蛋糕中实现持久性JVM功能?

时间:2011-01-14 18:44:00

标签: clojure jvm

我正在尝试了解cake如何实现其多种JVM方法。在高层次上,我认为蛋糕的工作方式类似于nailgun,其中有一个JVM实例(一个JVM进程),不同项目的新“JVM”实际上只是在一个新的类加载器中评估的clojure / jar(同时)不同的jar依赖项),在我看来不是一个新的JVM实例。但是,从What's the difference between Cake and Leiningen?可以看出,有多个JVM(一个用于cake,*用于项目),而不仅仅是一个JVM实例。

如果创建了新的JVM实例,那么加速是从哪里来的?根据我的理解,我认为启动一个新的JVM意味着创建一个新的JVM进程,它会像往常一样产生相同的启动开销。

如果没有,如何添加本机依赖项?据我所知,JVM只知道运行前传递的命令行参数的本机依赖关系。我知道如何规避这一点的唯一方法是使用下面列出的Sun / Oracle JVM实现特定的黑客。

 (let [clazz java.lang.ClassLoader
      field (.getDeclaredField clazz "sys_paths")] 
   (.setAccessible field true)
   (.set field clazz nil)
   (System/setProperty "java.library.path" (apply str (interpose ";" native-paths))))

2 个答案:

答案 0 :(得分:4)

Cake有一个Ruby脚本,可以启动和管理JVM。 Ruby没有JVM开销,因此Ruby脚本可以创建JVM,然后在执行命令时,Ruby脚本会将这些命令委托给JVM。

两个JVM必要的原因是,cake的依赖项(蛋糕JVM)与项目的依赖项(烘焙JVM)是​​分开的。像cake repl这样的命令在烘焙JVM中运行,以利用项目的类路径。

但是,在最新版本中,每个项目只有一个JVM。这可以在同一JVM中使用不同的类加载器。使用的相关库是classlojure

即使有两个JVM版本,JVM仍然是持久的,这意味着它们只生成一次,然后仅在绝对必要时重新启动,就像更改类路径的情况一样(当您添加新的依赖项或类似的东西时)。我不确定为什么你会认为这意味着每次执行命令都会产生JVM开销。这个想法是很多命令立即发生,而不是每个命令启动JVM。

答案 1 :(得分:2)

Raynes是对的。从蛋糕0.6.0开始,每个项目有一个JVM。 Cake在主类加载器中运行,并使用classlojure在单独的类加载器中加载项目,并在类路径更改时重新加载它。我们讨论了一个全局的〜/ .cake / config选项,在所有项目中共享一个JVM。使用classlojure添加它应该不会太难。这种方法的主要问题是如何将蛋糕任务插件分开。也许全球蛋糕项目可以在主要的类加载器中运行,每个项目可以获得两个类加载器(一个用于蛋糕,一个用于项目)。

对于本机依赖项,​​classlojure不支持在JVM启动后添加它们。只要本机库路径是特定类加载器的本地路径并且不在同一JVM中的所有类加载器之间共享,就可以使用添加此功能的补丁。