2011-01-14 5 views
5

Ich versuche zu verstehen, wie Kuchen seinen multiplen JVM-Ansatz implementiert. Auf einem hohen Niveau dachte ich, dass Kuchen ähnlich wie Nagelpistole funktioniert, wo es eine einzige JVM - Instanz gibt (ein JVM - Prozess), und neue "JVMs" für verschiedene Projekte wurden nur Clojure/Gläser in einem neuen Klassenlader evaluiert (zusammen mit verschiedene JAR-Abhängigkeiten), was in meinen Augen keine neue JVM-Instanz ist. Von What's the difference between Cake and Leiningen? gibt es jedoch eine Implikation, dass es mehrere JVMs gibt (eine für Kuchen und * für die Projekte), nicht nur eine einzelne JVM-Instanz.Wie wird die dauerhafte JVM-Funktion in Cake implementiert?

Wenn neue JVM-Instanzen erstellt werden, woher kommt die Beschleunigung? Mit meinem Verständnis würde ich meinen, dass das Starten einer neuen JVM impliziert, dass ein neuer JVM-Prozess erstellt wird, der denselben Startup-Overhead wie üblich verursacht.

Wenn nicht, wie werden native Abhängigkeiten hinzugefügt? Soweit ich weiß, kennt die JVM nur native Abhängigkeiten von Befehlszeilenargumenten, die vor der Laufzeit übergeben wurden. Der einzige Weg, wie ich dies umgehen kann, ist ein Sun/Oracle JVM-Implementierungs-Hack, der unten aufgeführt ist.

(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)))) 

Antwort

4

Cake hat ein Ruby-Skript, das die JVMs startet und verwaltet. Ruby hat keinen JVM-Overhead, daher könnte das Ruby-Skript die JVMs erstellen und wenn Sie dann Befehle ausführen, würde das Ruby-Skript diese Befehle an die JVMs delegieren.

Der Grund, warum zwei JVMs notwendig waren, war, dass die Abhängigkeiten des Kuchens (die Kuchen-JVM) getrennt von den Abhängigkeiten des Projekts (der Bake-JVM) waren. Einige Befehle wie cake repl werden in der Bake-JVM ausgeführt, um den Klassenpfad des Projekts zu nutzen.

In der neuesten Version gibt es jedoch nur eine einzige JVM pro Projekt. Dies ist mit verschiedenen Klassenladern in der gleichen JVM möglich. Die relevante verwendete Bibliothek ist classlojure.

Auch bei den beiden JVM-Versionen waren die JVMs persistent, das heißt, sie wurden nur einmal erzeugt und dann nur dann erneut gestartet, wenn dies unbedingt erforderlich ist, wie bei einem geänderten Klassenpfad (wenn Sie eine neue Abhängigkeit oder etwas Ähnliches hinzufügen). Ich bin nicht sicher, warum Sie denken würden, dass dies bedeuten würde, dass der JVM Overhead bei jeder Ausführung eines Befehls entsteht. Die Idee ist, dass viele Befehle sofort passieren und nicht jeder Befehl, der eine JVM startet.

+1

Danke. OK, mit der alten Version wurde pro Projekt eine neue JVM erstellt, ich hatte den falschen Eindruck, dass es wieder eher Nagelpistole war, wo es immer nur eine JVM-Instanz gibt. Die Methode der Nagelpistole war für mich in Bezug auf die Startzeit von JVM und das Ignorieren von Sicherheitsproblemen ideal, und ich bin mir bewusst, dass dies nicht die Art und Weise ist, wie Kuchen implementiert wird. Ich habe versucht, den Vorteil in Bezug auf die JVM-Startzeit in Situationen zu ermitteln, in denen die JVM neu gestartet oder erstellt werden musste, nicht bei jedem Cake-Befehl. – bmillare

+0

Unterstützt Classlojure das native Laden von nativen Abhängigkeiten? – bmillare

2

Raynes ist richtig. Ab Kuchen 0.6.0 gibt es eine JVM pro Projekt. Cake wird im Hauptklassenlader ausgeführt und verwendet classlojure, um das Projekt in einem separaten Klassenlader zu laden und neu zu laden, wenn sich der Klassenpfad ändert. Wir haben eine globale ~/.cake/config-Option besprochen, um eine einzige JVM unter allen Projekten zu teilen. Es sollte nicht schwer sein, dies mit classlojure hinzuzufügen. Das Hauptproblem bei diesem Ansatz ist, wie man die Cake-Task-Plugins getrennt hält. Vielleicht könnte das globale Kuchenprojekt im Hauptklassenlader laufen und jedes Projekt könnte zwei Klassenlader bekommen (einen für Kuchen und einen für das Projekt).

Wie bei nativen Abhängigkeiten unterstützt classlojure das Hinzufügen nicht, nachdem die JVM gestartet wurde. Ein Patch zum Hinzufügen dieser Funktionalität wäre willkommen, solange der native Bibliothekspfad für einen bestimmten Klassenlader lokal ist und nicht für alle Klassenlader in derselben JVM freigegeben ist.

+0

Die letzten beiden Anforderungen, die Sie erwähnen, sind leider (meines Wissens) unmöglich zu erfüllen. Darüber hinaus würde der oben angegebene Code brechen, wenn dieser mit verschiedenen JVM-Implementierungen ausgeführt würde. – bmillare

Verwandte Themen