2011-01-14 13 views
5

Próbuję zrozumieć, jak ciasto realizuje swoje wielokrotne podejście JVM. Na wysokim poziomie myślałem, że ciasto działa podobnie do gwoździarza, gdzie jest jedna instancja JVM (jeden proces JVM), a nowe "JVM" dla różnych projektów były w rzeczywistości tylko clojure/słoiki oceniane w nowym programie ładującym klasy (wraz z różne zależności słoików), co w moich oczach nie jest nową instancją JVM. Jednak od What's the difference between Cake and Leiningen? wynika, że ​​istnieje wiele maszyn JVM (jedna dla ciast i * dla projektów), a nie tylko jedna instancja JVM.W jaki sposób zaimplementowana jest trwała funkcja JVM w ciastku?

Jeśli są tworzone nowe instancje JVM, skąd pochodzi przyspieszenie? Rozumiem, że rozpoczęcie nowej maszyny JVM oznacza stworzenie nowego procesu JVM, który jak zwykle przynosi takie samo obciążenie podczas uruchamiania.

Jeśli nie ma, w jaki sposób dodawane są rodzime zależności? Z tego co rozumiem, JVM wie tylko o natywnych zależnościach od argumentów wiersza poleceń przekazanych przed uruchomieniem. Jedyny sposób, w jaki wiem, jak obejść ten problem, to konkretne włamanie do maszyny wirtualnej/Oracle JVM wymienione poniżej.

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

Odpowiedz

4

Ciastko ma skrypt Ruby, który uruchamia JVM i zarządza nimi. Ruby nie ma narzutów maszyny JVM, więc skrypt Ruby mógł utworzyć maszyny JVM, a następnie po wykonaniu poleceń skrypt Ruby przekazałby te komendy do maszyn JVM.

Powodem, dla którego dwa JVM były niezbędne, było to, że zależności tortu (ciasto JVM) były oddzielne od zależności projektu (piec JVM). Niektóre polecenia, takie jak cake repl, są uruchamiane w wirtualnej maszynie JVM, aby skorzystać ze ścieżki klas projektu.

Jednak w najnowszej wersji na projekt jest tylko jedna JVM. Jest to możliwe przy użyciu różnych programów ładujących klasy w tej samej maszynie JVM. Odpowiednią używaną biblioteką jest classlojure.

Nawet z dwiema wersjami JVM maszyny JVM były trwałe, co oznacza, że ​​były tworzone tylko raz, a następnie ponownie uruchamiane tylko wtedy, gdy jest to absolutnie konieczne, tak jak w przypadku zmienionej ścieżki klasy (podczas dodawania nowej zależności lub czegoś podobnego). Nie jestem pewien, dlaczego myślisz, że to oznaczałoby ponoszenie obciążenia JVM za każdym razem, gdy polecenie zostanie wykonane. Chodzi o to, że wiele poleceń dzieje się natychmiast, a nie każde polecenie uruchamiające JVM.

+1

Dzięki. OK, ze starą wersją, nowa JVM została stworzona dla każdego projektu, miałem złe wrażenie, że znowu było bardziej zbliżone do nailgun, gdzie jest tylko jedna instancja JVM. Metoda z użyciem pistoletu gwoździowego była idealna w moim umyśle w odniesieniu do czasu uruchamiania JVM i ignorowania problemów związanych z bezpieczeństwem, które zdaję sobie sprawę, że nie jest to sposób w jaki ciasto jest zaimplementowane. Próbowałem ustalić korzyści związane z czasem uruchamiania JVM w sytuacjach, w których JVM musiała zostać zrestartowana lub utworzona, a nie za każde polecenie tortu. – bmillare

+0

Czy klasyczna obsługa ładowania rodzimego jest zależna od czasu wykonywania? – bmillare

2

Raynes jest poprawny. Od wersji 0.6.0 na projekt jest jedna JVM. Cake uruchamia się w głównym programie ładującym klasy i używa classlojure do załadowania projektu do oddzielnego programu ładującego klasy i przeładowania go, gdy zmieni się ścieżka klasy. Omówiliśmy globalną opcję ~/.cake/config, aby udostępnić pojedynczą maszynę JVM spośród wszystkich projektów. Dodanie tego do klasy classlojure nie powinno być zbyt trudne. Głównym problemem związanym z tym podejściem jest oddzielanie wtyczek zadań tortów. Być może projekt globalnego tortu mógłby działać w głównym programie ładującym klasy, a każdy projekt mógł otrzymać dwa programy ładujące klasy (jeden na ciasto i jeden na projekt).

Co do rodzimych zależności, classlojure nie obsługuje dodawania ich po uruchomieniu JVM. Poprawka do dodania tej funkcji byłaby mile widziana, o ile ścieżka do biblioteki rodzimej jest lokalna dla określonego programu ładującego klasy i nie jest udostępniana wszystkim klasom ładującym w tej samej maszynie JVM.

+0

Te dwa ostatnie wymagania, które wymieniłeś, niestety, są zasadniczo niemożliwe do spełnienia (według mojej wiedzy). Ponadto kod podany powyżej zostałby złamany, gdyby był uruchamiany przy różnych implementacjach JVM. – bmillare

Powiązane problemy