dimensione booleana non definita in java: perché?

7

Vedo che la dimensione di booleano non è definita. Di seguito sono riportate due affermazioni che vedo in dimensioni dei dati primitivi java

not precisely defined

Ulteriori spiegazioni dice

boolean represents one bit of information, but its "size" isn't something that's precisely defined.

Mi è venuto in mente il motivo per cui booleano in java non può essere rappresentato con 1 bit (o 1 byte se il byte è la rappresentazione minima)?

Ma vedo che ha già risposto a link dove dice

the JVM uses a 32-bit stack cell, used to hold local variables, method arguments, and expression values. Primitives that are smaller than 1 cell are padded out, primitives larger than 32 bits (long and double) take 2 cells

Significa che anche i tipi di dati primitiva di byte / char / short prendono anche 32 bit sebbene la loro dimensione sia definita come 8/16/16 bit?

Possiamo anche dire che le dimensioni booleane saranno 32 bit su cpu a 32 bit e 64 bit su cpu a 64 bit?

    
posta user3222249 02.01.2018 - 17:45
fonte

2 risposte

9

TL; DR l'unica cosa certa è che boolean occupa almeno un bit. Tutto il resto dipende dall'implementazione della JVM.

La specifica del linguaggio Java non definisce le dimensioni, solo gli intervalli di valori (vedi The Language Spec ). Quindi, non è solo la dimensione boolean che non è definita a questo livello. E boolean ha due possibili valori: false e true .

La Specifica della macchina virtuale dice noi che boolean variabili sono trattate come int con valori 0 e 1. Solo le matrici di boolean hanno un supporto specifico. Pertanto, a livello di Macchina virtuale, una variabile boolean occupa la stessa quantità di spazio di int , ovvero una pila: almeno 4 byte, in genere 4 byte su Java a 32 bit e 8 byte su 64 bit.

Infine c'è il motore HotSpot che compila il bytecode JVM in un codice macchina ottimizzato per CPU specifico, e scommetto che in molti casi è in grado di dedurre il valore limitato di un int -masked boolean dal contesto e usa una dimensione più piccola.

    
risposta data 02.01.2018 - 21:23
fonte
7

Ci sono una serie di concetti da sfatare:

  • il linguaggio di programmazione Java stesso, che è un linguaggio di programmazione testuale,
  • codice byte Java Virtual Machine & formato di file di classe , che è una codifica binaria compilata del codice sorgente della lingua Java originale e viene utilizzato come un formato di file di interscambio per memorizzare, caricare e condividere il codice oggetto java,
  • una particolare implementazione di Java Virtual Machine, che potrebbe essere un interprete, sebbene spesso sia un'implementazione basata su JIT,
  • codice macchina generato JIT che viene eseguito direttamente sul processore hardware.

Java, il linguaggio di programmazione , non definisce una dimensione di concetto di tipi primitivi perché (a differenza di C / C ++) non esiste l'operatore sizeof : le dimensioni non sono osservabili tramite costrutti del linguaggio, quindi il linguaggio non ha bisogno di definirli.

Come @Ralf indica che il linguaggio Java definisce l'intervallo dei tipi primitivi, che è molto rilevante per il programmatore in quanto questi intervalli possono essere osservati tramite costrutti all'interno del linguaggio.

Il linguaggio definisce una capacità di strumentazione che consente l'indagine sulla dimensione di un oggetto, ma (1) ciò richiede la strumentazione, (2) fornisce solo una stima, e (3) questa indagine non si applica alle primitive tipi o variabili locali.

the JVM uses a 32-bit stack cell, used to hold local variables, method arguments, and expression values. Primitives that are smaller than 1 cell are padded out, primitives larger than 32 bits (long and double) take 2 cells

La citazione di padding parla dei dettagli del formato di file di classe JVM, che viene utilizzato come meccanismo di interscambio (distinto dal linguaggio Java e un'implementazione JVM). Anche se quello che dice vale per la macchina astratta e il codice byte JVM, non deve necessariamente contenere il codice macchina JIT.

La citazione di padding si limita anche alla discussione di variabili / parametri / espressioni locali che sono tipicamente stack allocati (ad esempio auto o automatismi in C / C ++) e non discute oggetto / array.

La dimensione effettiva di tali variabili automatiche non è quasi mai un problema (ad esempio per le prestazioni o per lo spazio).

In parte, questo è dovuto al fatto che le CPU hardware sottostanti funzionano più naturalmente su dimensioni di bit più grandi (come 32 o 64) piuttosto che a 1 bit. Anche le dimensioni a 8 o 16 bit non sono generalmente più veloci di 32, e talvolta la gestione a 8 bit richiede un'istruzione aggiuntiva o due per lavorare con i registri più ampi del set di istruzioni hardware.

E un'altra ragione è l'uso limitato di variabili locali - sono usate direttamente dal codice e solo dal codice, e quindi non sono realmente soggette a problemi di ridimensionamento - in particolare, rispetto a oggetti e matrici, che sono usati dalle strutture di dati di potenzialmente qualsiasi scala.

(Potremmo considerare la ricorsione come ridimensionamento delle variabili locali, quindi le variabili locali più grandi nelle routine ricorsive rischiano di sovraccaricare lo straripamento più rapidamente.)

Tuttavia, le dimensioni degli oggetti possono essere molto importanti, se il conteggio delle istanze è elevato e anche le dimensioni degli elementi dell'array possono avere importanza se hanno un numero elevato di elementi.

Does it mean even byte/char/short primitiva data types also take 32 bit though their size is defined as 8/16/16 bit ?

Per la gente del posto, forse, forse non dipende dal JIT.

Per oggetti, all'interno del codice byte JVM & meccanismo di file di classe, i campi sono direttamente accessibili tramite la loro identificazione e non vi è alcuna nozione di "celle" - mentre esiste con le variabili (locale e parametro).

Un'implementazione JVM (incluso il suo JIT) ha la flessibilità di riorganizzare l'ordine dei campi all'interno dell'implementazione (ad esempio a livello di codice macchina) in modo che due campi a 16 bit possano occupare la stessa parola a 32 bit anche se non fossero dichiarati adiacenti il codice sorgente; questo riduce il sovraccarico causato dall'imbottitura necessaria per mantenere l'allineamento. Qualsiasi alling, padding e field placement di questo tipo sono anche problemi di implementazione di JVM piuttosto che di formati di interscambio JVM. In teoria, il JIT potrebbe impacchettare i booleani a un bit in un array, o impacchettare 8 singoli campi booleani in un singolo byte in un oggetto. La maggior parte non è una scelta di implementazione JVM.

    
risposta data 02.01.2018 - 23:34
fonte

Leggi altre domande sui tag