Cosa impedisce a Java di raggiungere la portabilità a livello C?

4

Laddove la portabilità viene definita generalmente come la percentuale di piattaforme su cui un linguaggio o una tecnologia possono essere eseguite, C / C ++ viene spesso citato come più portatile di Java, poiché un'applicazione Java dipende da una JVM presenti.

Ma cosa impedisce a un'applicazione Java di spedire entro un wrapper JVM? O essere transpiled in C / C ++ con un framework di supporto? (Essenzialmente una JVM, ma come una libreria di supporto invece di un wrapper / contenitore.)

C'è un problema tecnico? Un problema di licenza? Oppure, semplicemente che nessuno ha deciso di farlo!?

Prendendo un esempio concreto, considera il secondo punto della prima risposta a " Perché Java non è più utilizzato per lo sviluppo di giochi? ", che afferma che:

Most consoles (e.g., 360, PS3) do not have a JVM, so you cannot reuse code from the PC version. It is much easier to compile C++ code to support various devices.

Se questa affermazione è corretta (per quanto riguarda la maggior parte delle console), la mancanza di JVM per queste piattaforme è dovuta a limitazioni tecniche? Legale? Politico? ecc.

Quando si afferma che Java "non può" essere eseguito su console di gioco (o iPhones), intendiamo veramente non può!? o, intendiamo, "nessuna build disturbata l'impianto idraulico necessario? "

    
posta svidgen 26.01.2018 - 18:21
fonte

5 risposte

13

Java è portatile nel senso che C o C ++ può essere portatile: lo stesso codice sorgente può essere utilizzato per più sistemi operativi o architetture di processore. In realtà questo è molto più semplice in Java, dal momento che la JVM riassume molti dettagli specifici della piattaforma (come le dimensioni di una long int , o endianness) e gli estratti della libreria standard sulla funzionalità fornita dal sistema operativo (es. per aprire un file).

Per C e C ++, la cosa migliore da fare è attenersi allo standard POSIX che offre almeno la portabilità di origine su Unix e Linux, ma in particolare esclude Windows senza WSL o Cygwin. E a differenza di Java, una base di codice portatile deve essere ricompilata per ogni piattaforma mirata. Ciò che rende C e C ++ "più portabile" è che i cross-compilatori come GCC tendono ad avere molte piattaforme di destinazione (per supportare un nuovo platfom di destinazione, "solo" è necessario creare un nuovo backend del compilatore).

Java 9 introduce la possibilità di trasformare un'applicazione Java in un eseguibile autonomo che include tutte le parti necessarie di Java Runtime. Ma sei ancora limitato dalla portabilità della tua JVM. E il pacchetto deve essere costruito sul sistema operativo di destinazione.

La JVM in sé è un programma che può essere o non essere portatile. Per esempio. HotSpot è un programma C ++ che può essere portato su nuovi sistemi operativi o architetture.

Ma cosa succede se stiamo mirando a un dispositivo incorporato che potrebbe non eseguire un sistema operativo completo o potrebbe avere vincoli hardware? Questo diventa più difficile per C e Java allo stesso modo. Ma ci sono JRE incorporati, e per entrambe le classi di linguaggi la soluzione riguarda la scelta di una libreria standard più piccola. Java 9 rende possibile selezionare i moduli al momento della compilazione, piuttosto che dover scegliere come target un profilo predefinito come Java ME.

Un caso d'uso in cui C vince sta lavorando in assenza di un sistema operativo, visualizzato direttamente su un microcontrollore. Non è possibile utilizzare la libreria standard (ad es. Per aprire i file o l'allocazione dinamica della memoria), ma la lingua principale è ancora lì. Ma non è ragionevole limitare il significato di "portabilità" a "può funzionare senza la libreria standard".

Sistemi bloccati come iOS o console non consentono l'installazione di software arbitrario, anche se sono fisicamente in grado di eseguire quel software - sono generalmente costruiti da CPU standard, usando kernel standard. L'assenza di una JVM su questi sistemi è semplicemente una conseguenza del gatekeeper (ad esempio Apple o Nintendo) che non è interessato a consentire una piattaforma separata che non è sotto il loro controllo. Quindi questa assenza è legale / politica.

    
risposta data 26.01.2018 - 19:06
fonte
6

a Java application depends on a JVM being present.

Questo non è vero. Non c'è nulla nella specifica del linguaggio Java che dica qualcosa sulla JVM. Oracle è piuttosto severo nel mantenere i due separati.

E, in effetti, esiste una piattaforma di telefonia mobile molto popolare di Google che utilizza ampiamente Java senza JVM.

But, what prevents a Java application from shipping within a JVM wrapper? Or being transpiled to C/C++ with a supporting framework? (Essentially a JVM, but as a supporting library instead of a wrapper/container.)

Niente.

Is there a technical issue? A licensing issue? Or, simply that no one has decided to do it!?

Sì.

Most consoles (e.g., 360, PS3) do not have a JVM, so you cannot reuse code from the PC version. It is much easier to compile C++ code to support various devices. If this claim is correct (with regards to "most" consoles), is the lack JVM for these platforms due to technical limitations?

No.

Legal? Political? etc.

Probabilmente.

Oppure, nessuno ha ancora fatto il lavoro.

When it's stated that Java "can't" be run on game consoles (or iPhones), do we really mean can't!? Or, do we mean, "no one's bothered build the necessary plumbing?"

Apple non ammette app in grado di eseguire codice che non fa parte dell'app. Ciò renderebbe una JVM pura piuttosto inutile.

Nota, ovviamente, che puoi avere un'app che include il codice dell'applicazione e una JVM in un'unica app. Ma ogni app dovrebbe avere la sua copia della JVM.

    
risposta data 26.01.2018 - 23:28
fonte
2

But, what prevents a Java application from shipping within a JVM wrapper?

Penso che tu abbia sbagliato: se c'è un'implementazione JVM, la battaglia è già vinta, indipendentemente dal fatto che JVM sia spedito separatamente o incorporato nell'app. Il problema è scrivere la JVM in primo luogo.

Per inciso, quando la gente parla di "portabilità", di solito significa "puoi ricompilare questo codice sorgente con poche modifiche e farlo funzionare su un'altra piattaforma", non solo "c'è un runtime / compilatore per questa piattaforma" ( sebbene, ovviamente, quest'ultimo sia un requisito). In questo senso, Java è portatile quanto C, vale a dire: il codice semplice verrà eseguito così com'è, ma alcune librerie potrebbero non essere disponibili e alcune ipotesi sulla memoria potrebbero essere errate. Si noti che sebbene sia probabile l'implementazione di un compilatore C per quasi tutte le piattaforme a cui si può pensare, molti programmi C non banali non possono essere fatti funzionare su un'altra piattaforma semplicemente ricompilando, a causa di API, librerie, ipotesi di memoria e altre dipendenze. / p>

When it's stated that Java "can't" be run on game consoles (or iPhones), do we really mean can't!? Or, do we mean, "no one's bothered build the necessary plumbing?"

Non c'è alcun motivo tecnico per cui Java non possa funzionare su iPhone, Nintendo Switch o altre console. Se non c'è un'implementazione JVM, di solito significa che ci sono dei motivi legali (che è probabilmente il caso per l'iPhone e per l'hardware proprietario con gli SDK ufficiali), o non ha senso perché c'è già un SDK ampiamente usato con librerie utili per un'altra lingua, o entrambe.

    
risposta data 26.01.2018 - 20:49
fonte
2

TL; DR : oltre ai problemi legali / aziendali, altri già menzionati, esistono effettivamente limitazioni tecniche. In parole povere, creare una JVM ragionevolmente buona è più difficile di un compilatore C ragionevolmente buono. Quindi, mentre teoricamente possibile, molte porte non vengono create semplicemente a causa dello sforzo richiesto.

Quindi quali sono le sfide? Ci sono almeno tre elementi importanti di un'implementazione Java funzionante: supporto per l'analisi e la compilazione della lingua stessa, implementazione della libreria standard e creazione della JVM che offre un ambiente in cui vengono eseguite le applicazioni compilate.

Per quanto riguarda la lingua, Java ha molte funzioni che C manca , come l'orientamento agli oggetti, molte validazioni imposte dalle specifiche del linguaggio (controllo dei limiti degli array, convalida bytecode prima che le classi siano caricate, ecc. .), un gestore della sicurezza, caricamento della classe run-time, un modello di memoria che dice esattamente come si suppone che il codice multi-threaded si comporti, e alcune altre caratteristiche oscure che molti sviluppano non si rendono nemmeno conto ci sono, ma quali sono le specifiche del linguaggio descrive in grande dettaglio. Tutto ciò fa sì che diverse implementazioni Java siano molto più simili l'una all'altra in termini di comportamento del programma rispetto ai diversi compilatori C, ma ha il costo di dover comprendere e implementare molte e molte funzionalità.

Quindi, c'è la libreria standard che è anche abbastanza ricca. La maggior parte di esso è scritta in Java, ma esiste anche un codice nativo utilizzato per motivi di prestazioni o perché la libreria funziona a un livello basso che non è disponibile direttamente da Java puro se non fosse per le librerie (ad esempio la concorrenza di basso livello codice).

E infine c'è la JVM che è un diavolo di mostro . Esegue molte operazioni che sono molto complesse da implementare e anche più difficili da implementare correttamente: garbage collection, compilazione just-in-time, caricamento e scaricamento di classi, interfacciamento con il codice nativo mantenendo l'integrità della JVM. Dai un'occhiata a A JVM? per un elenco parziale. Implementare tutto questo mantenendo alte prestazioni è un compito molto difficile e ci sono davvero poche persone in grado di farlo.

Oltre alla complessità dell'implementazione, ci sono anche alcuni costi di prestazione . Mentre i programmi Java possono essere veramente veloci al giorno d'oggi, questo è possibile solo grazie a molti trucchi molto intelligenti implementati dalla JVM. L'implementazione di una JVM senza le ottimizzazioni farebbe rallentare tutti i programmi e renderebbe l'intero porto piuttosto inutile. C'è anche un sovraccarico di memoria che è difficile da evitare. Questo non è un grosso problema per un PC o un server, ma per ambienti più ristretti lo è. Ci sono anche molti dati di cui la stessa JVM ha bisogno: l'intera libreria standard complessa. O il database Unicode che ha almeno alcuni megabyte di dimensioni se non sbaglio.

Naturalmente, se non è così semplice creare una JVM per una nuova piattaforma, è altrettanto difficile creare un transpiler o qualcosa che componga Java in binari nativi, poiché i binari effettivamente devono contenere la JVM o di grandi dimensioni parti di questi.

In Java 9, l'obiettivo principale era la modularizzazione , il che significa che per la prima volta il tuo programma Hello Hello potrebbe non aver bisogno di includere 50 MB di librerie solo per avviare la JVM. Questo è un passo importante nella giusta direzione, ma c'è ancora molta strada da fare prima che Java possa essere eseguito in ambienti ristretti come C. J2ME è in realtà solo un sottoinsieme dello stack Java completo.

    
risposta data 27.01.2018 - 10:17
fonte
1

Dimensioni e velocità sono due fattori enormi. Una JVM è un programma piuttosto grande che richiede un sacco di RAM e spazio di archiviazione da utilizzare. Anche una JVM è spesso più lenta (a seconda del flusso di lavoro).

Ciò significa che Java non è adatto per la programmazione embedded (ovviamente a seconda di quanto piccolo pensi che sia embedded). Ad esempio, prova ad eseguire java su un microcontrollore a 8 bit, ad esempio un arduino.

Modifica:

Java Card è sottoinsieme (!) di java con requisiti minimi di sistema di 16 kB ROM, EEPROM da 8 kB e 256 byte di RAM. Anche se questo è piccolo, non è così piccolo come C può gestire. In realtà è piuttosto gonfio. Java Card usa aritmetica a 16 bit, il che significa che non verrà eseguito (bene) su una CPU a 8 bit.

Per J2ME i requisiti sono ancora più grandi, quindi lascio che sia fuori discussione.

Per favore, non sottovalutare questa risposta senza dimostrare che la mia affermazione è errata, cioè mostrami java in esecuzione su un sistema a 8 bit con limitazioni elevate.

    
risposta data 26.01.2018 - 18:42
fonte

Leggi altre domande sui tag