JVM'yi bu kadar çok JVM dilini desteklemek için bu kadar çok yönlü yapan nedir?


18

JVM, Java gibi pek çok dili destekler ve Java'nın Groovy,Clojure,Scalaaksine işlevsel dillerdir ( desteklenmeyen yerlerde Sürüm 8'den önce Java'ya atıfta bulunuyorum Lambda's). hem Nesne Odaklı hem de İşlevsel dilleri destekleyebilir mi?


"Fonksiyonel Groovy, Clojure, Scala vb.". Bunlardan bazıları diğerlerinden daha işlevsel. Groovy ile en az fonksiyonel ve en çok Clojure ile, Scala ortada bir ölçek kullanıyordum.
Vorg van Geir

Yanıtlar:


37

Diğer VM'lerle karşılaştırıldığında , JVM aslında çok yönlü değildir . Statik olarak yazılan OO'yu doğrudan destekler. Diğer her şey için, hangi parçaları kullanabileceğinizi ve dilinizin ihtiyaç duyduğu her şeyi bu parçaların üzerine nasıl inşa edebileceğinizi görmelisiniz.

Örneğin, Java 7 invokedynamicbayt kodunu tanıtana kadar, JVM'ye dinamik olarak yazılmış bir OO dili uygulamak çok zordu - performans için kötü olan ve korkunç bir şekilde şişirilmiş yığın izleriyle sonuçlanan karmaşık geçici çözümler kullanmanız gerekiyordu.

Yine de, daha önce JVM'ye bir dizi dinamik dil (Groovy, Jython, JRuby) uygulandı.

JVM çok yönlü olduğu için değil, çok yaygın olduğu ve çok olgun, iyi desteklenen ve yüksek performanslı uygulamalara sahip olduğu için.

Ve belki daha da önemlisi, orada hemen hemen her şeyi yapan çok sayıda Java kodu olduğundan ve diliniz JVM'de çalışıyorsa, bu kodla entegre etmek için kolaylıklar sunabilirsiniz. Temel olarak, dilinizin JVM'de yayınlanması, C ile birlikte çalışabilirlik sunan 21. yüzyıl versiyonudur.


İyi cevap (+1). Bahsettiğiniz son nokta, IMHO'nun Java'nın bir dil olarak popülerliğinden de sorumlu olmasıdır: Sonunda, ücretsiz olarak kullanabileceğiniz çok sayıda koda sahip olmak, en son ve en moda dili kullanmaktan çok daha fazla zaman kazandırabilir özellikleri.
Giorgio

4

JVM temel olarak bir CPU gibi davranmak için yazılmıştır, VM'nin bytecodes olarak adlandırdığı bir takım talimatlar, bir çeşit montaj vardır. Geçerli bir bayt kodu kümesi oluşturan bir derleyici yazabiliyorsanız, JVM bunları çalıştırabilir.

Wikipedia bayt kodlarının bir listesine sahiptir:

http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

ve JVM'nin bayt kodlarını nasıl yüklediğine dair bir açıklama:

http://en.wikipedia.org/wiki/Java_virtual_machine

Çağırma stili bayt kodlarını kullanarak, işlevsel bir dil, kaynağın nasıl göründüğüne bakılmaksızın kodu yürütebilir. Ayrıca, invokevirtual'un eklenmesiyle, jruby gibi dil uygulamaları nasıl çalıştıklarına dair bir miktar esneklik vermektedir.


1
Aynı şey, diğer tüm VM'ler için de geçerlidir: YARV Ruby VM, Rubinius Ruby VM, CPython VM (sonuçta JVM'den önce gelir), Parrot, çeşitli Smalltalk ve Lisp VM'leri ve elbette Pascal P- Kod sistemi, bundan sonra JVM modellenmiştir.
Jörg W Mittag

Anlaşılan, JVM kesinlikle orada ilk VM değil. JVM, diğer diller için popüler olduğunu düşünüyorum çünkü Java popüler, VM aktif olarak geliştirilmiş ve iyi belgelenmiş.
sasbury

2

JVM'nin iyi tanımlanmış ve oldukça iyi bir Bellek Modelini ( JMM ) desteklediğini ve tutarlı (düşük düzeyde de olsa) iş parçacığı davranışı için iyi bir destek anlamına geldiğini ekleyeceğim . Aynı zamanda güçlü bir Just In Time var derleyicisine (MethodHandles ve invokedynamic sayesinde dinamik diller için artık kullanışlı değil).

Son olarak, JVM'nin (doğru ayarlamayla) üstteki dilden bağımsız olarak belleği sizin için yöneten Çöp Toplama alt sistemi .


JMM, Java ile ilgili en az sevdiğim şeylerden biri. Ben etkili bir şekilde değiştirilemeyen verilerin hayranıyım (örneğin, içeriği diğer iş parçacıklarına görünür olduktan sonra asla değişmeyecek diziler), ancak someField = new int[]{42};yeni diziyi gören herhangi bir iş parçacığının değeri görmesini sağlamanın tek yolu gibi bir ifade verildi 42 ya alan yapmak ya finalda volatile. Alan tembel bir şekilde oluşturulur, ancak sık sık erişilirse, finalçalışmaz hale getirilmesi ve volatileher erişildiğinde gereksiz bir senkronizasyon cezası uygulanmasına neden olabilir. En gevşek .NET modelinde bile ...
supercat

... kod, dizi popülasyonunun başvuru deposundan önce gerçekleşmesini isteyebilir. Alanı okuyan diğer iş parçacıkları yeni diziye başvuruyu görebilir veya görmeyebilir, ancak yeni diziyi görürlerse içeriğini göreceklerinden kendileri için hiçbir ücret ödemeyeceklerinden emin olabilirsiniz.
supercat

1

Buradaki anahtar unsur, derlemenin yürütme aşamasından ayrılmasıdır. Böylece bayt koduna diğer dilleri derleyen başka derleyiciler yazmak da mümkündür.

Bayt kodu, bir CPU'nun makine koduna benzer şekilde davranır - bir programı çalıştırmak için gereken tüm küçük işlemlere sahipsiniz - bir değişken alabilir, üzerinde matematik yapabilir, koşullu işlemlere vb.

Java da özel değil. Java'da, diğer sanal makinelerin aksine, birden çok dilin varlığı bir tasarım hedefi bile değildi. İçin Microsoft'un .Net CIL (... C #, VB.Net) birden çok dil çalıştırma yeteneği de önemli bir tasarım öğesi, oldu ParrotVM genel VM olması amaçlanmıştır Perl6 projesinden.

Eğlenmek için bir zamanlar bir kanıt oluşturdum PHP'nin Zend Engine'in bile buna izin verebileceğine dair .

Ve açıkçası bu yeni bir şey değil - gerçek donanımda bile birden fazla dil çalıştırabilirsiniz - yani C veya Fortran.

Derleme ve yürütmeden bu ayrılığın farkı, bazı Temel, kabuk komut dosyaları vb.Gibi clssic tercümanlardır, genellikle kodu hemen bir forma getirmeden satır satır daha fazla veya daha az yürütecek şekilde çalışırlar arasında.


1

JVM, çöp toplama, performans ve uygulanabilir bir sanal alan modelini bir araya getiren ilk sanal makinedir. JVM'yi desteklemek için birçok dilin ortaya çıkması muhtemelen "çok yönlülüğünün" bir sonucu değil, Java dilinin insanların bir programlama dilinde istediği bazı önemli özelliklerden yoksun olmasıdır. Örneğin, çoğu makine dili sadece yarım düzine kadar veri türüne sahipken (örn. Bayt, yarım sözcük, sözcük, çift sözcük, tek duyarlıklı kayan sayı ve çift duyarlık kayan sayı), programlama dillerinin büyük çoğunluğu kodun kullanılmasına izin verir isteğe bağlı sayıda kullanıcı tanımlı veri türü. JVM, tipik bir makinedekine benzer birkaç ilkel türü ve bir tane daha türü tanır: Geçici Nesne Referansı. Java dili de bu ilkelleri tanır, ve Karışık Nesne Referansları. Bir değişken, belirli bir sınıf olmayan herhangi bir şeye referans vermeyecek şekilde kısıtlanabilirken, dil aşağıdaki türdeki alanlardan hiçbiri arasında ayrım yapmazList<String>örnek MyThingsınıfı tarafından tutulabilecek MyClass:

  • Bir şeye kod referansı, değişmez bir uygulama olduğunu bilir List<String>

  • Mutasyona uğrayabilecek hiçbir şeye maruz kalmayacak bir değişken liste türü örneğine başvuru.

  • MyThingsYöntemlerinin yürütülmesi haricinde , evrenin hiçbir yerinde başka bir referansın bulunamayacağı değiştirilebilir bir listeye başvuru.

  • Başka bir nesneye ait olan ve diğer nesnenin bir MyThingşekilde kullanmak istediği değiştirilebilir bir listeye başvuru .

  • Sahip MyThingolduğu, ancak onunla bir şeyler yapabilmeleri için diğer bazı nesnelere de maruz kaldığı değiştirilebilir bir listeye başvuru .

Tüm bu alanların türü olsa da List<String>, çok farklı şeyler tutarlar. Etkileyici bir dil, bu anlamlar arasında bir ayrım yapılmasına izin verebilir, ancak Java izin vermez. Bir dil bu tür şeylere anlam yükleyebildiğinden (en azından genel bağlamların dışında) ve JVM'de çalışabildiğinden, JVM hedefli dillerin Java'nın yapamayacağı kavramları ifade etmesi için çok yer kalır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.