Qual è la dimensione di una variabile booleana in Java?


89

Qualcuno può dire la dimensione in bit di booleano in Java?


1
Lo stesso è chiesto qui: stackoverflow.com/questions/1907318/...
dma_k

Risposte:


41

Dipende dalla macchina virtuale.


9
Ti va di indicare alcuni documenti? Trovo difficile credere che la dimensione di un booleano dipenda dalla macchina. Ciò significherebbe che la rappresentazione binaria di una classe contenente un booleano avrebbe dimensioni (e layout di memoria) diversi in VM diverse e ciò implicherebbe che le VM non sarebbero compatibili.
David Rodríguez - dribeas

14
Penso che fosse implicito che la domanda si riferisse alla dimensione di una variabile booleana in memoria, non alla dimensione di una variabile booleana codificata in un file di classe. La dimensione della memoria varia in base alla VM in base alla documentazione di Sun. La dimensione nel file di classe è costante.
William Brendel

3
@ DavidRodríguez-dribeas - La JVM Sun all'epoca di Java 1.1 utilizzava 4 byte per booleano quando veniva memorizzata come istanza o auto var. Ciò ha semplificato l'implementazione dell'interprete bytecode (che considera i bool come occupanti 4 byte nello stack) ed è stato il percorso di minor resistenza. Quando abbiamo implementato la JVM iSeries "Classic" abbiamo trovato il modo per rendere le istanze variabili di 1 byte, in quanto ciò ha notevolmente migliorato la compattezza di alcuni oggetti (che ha un impatto sorprendente sulle prestazioni). Apparentemente, sulla base dei post seguenti, gli sviluppatori Sun / Oracle hanno capito come fare lo stesso nelle versioni successive.
Hot Licks

Ma è giusto, alla fine del 2017 JavaDocs dice: boolean: The boolean data type... This data type represents one bit of information, but its "size" isn't something that's precisely defined- ma il tuo punto è valido, potrebbe usare alcuni link e informazioni migliori :)
JimLohse

185

Dipende dalla macchina virtuale, ma è facile adattare il codice da una domanda simile che chiede i byte in Java :

class LotsOfBooleans
{
    boolean a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
    boolean b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
    boolean c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
    boolean d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
    boolean e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
}

class LotsOfInts
{
    int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
    int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
    int c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
    int d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
    int e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
}


public class Test
{
    private static final int SIZE = 1000000;

    public static void main(String[] args) throws Exception
    {        
        LotsOfBooleans[] first = new LotsOfBooleans[SIZE];
        LotsOfInts[] second = new LotsOfInts[SIZE];

        System.gc();
        long startMem = getMemory();

        for (int i=0; i < SIZE; i++)
        {
            first[i] = new LotsOfBooleans();
        }

        System.gc();
        long endMem = getMemory();

        System.out.println ("Size for LotsOfBooleans: " + (endMem-startMem));
        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));

        System.gc();
        startMem = getMemory();
        for (int i=0; i < SIZE; i++)
        {
            second[i] = new LotsOfInts();
        }
        System.gc();
        endMem = getMemory();

        System.out.println ("Size for LotsOfInts: " + (endMem-startMem));
        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));

        // Make sure nothing gets collected
        long total = 0;
        for (int i=0; i < SIZE; i++)
        {
            total += (first[i].a0 ? 1 : 0) + second[i].a0;
        }
        System.out.println(total);
    }

    private static long getMemory()
    {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }
}

Per ribadire, questo dipende dalla VM, ma sul mio laptop Windows con build 1.6.0_11 di Sun JDK ho ottenuto i seguenti risultati:

Size for LotsOfBooleans: 87978576
Average size: 87.978576
Size for LotsOfInts: 328000000
Average size: 328.0

Ciò suggerisce che i booleani possono essere fondamentalmente impacchettati in un byte ciascuno dalla JVM di Sun.


21
@skeet - Ti saluto davvero. La tua risposta è fantastica
Warrior

2
@warrior: Dato che avevo già il codice per "byte", cambiarlo in "booleano" è stato piuttosto semplice :)
Jon Skeet

3
System.gc () non garantisce la pulizia della memoria. Dà semplicemente un ordine alla JVM per eseguire la garbage collection, ma non significa che il collector abbia effettivamente pulito qualcosa. Ricorda che il raccoglitore pulisce gli oggetti NON UTILIZZATI. Un oggetto è inutilizzato se il programma non contiene più riferimenti ad esso. Quindi nel tuo test eliminerei esplicitamente il riferimento impostando LotsOfBooleans su null prima di eseguire gc (); O semplicemente eseguire main una volta con boolean, una volta con int quindi confrontare i numeri.
Randa Sbeity

2
@RandaSbeity O ancora meglio: assicurati di conservare entrambi i riferimenti e di calcolare la differenza di memoria. Che è esattamente quello che succede qui.
biziclop

1
C'è qualche domanda a cui Jon Skeet non può rispondere?
Andreas Hartmann

31

Le informazioni effettive rappresentate da un valore booleano in Java sono un bit: 1 per vero, 0 per falso. Tuttavia, la dimensione effettiva di una variabile booleana in memoria non è definita con precisione dalla specifica Java. Vedere Tipi di dati primitivi in ​​Java .

Il tipo di dati booleano ha solo due possibili valori: vero e falso. Usa questo tipo di dati per flag semplici che tengono traccia di condizioni vere / false. Questo tipo di dati rappresenta un bit di informazione, ma la sua "dimensione" non è definita con precisione.


21

In una nota a margine...

Se stai pensando di utilizzare un array di oggetti booleani, non farlo. Usa invece un BitSet: ha alcune ottimizzazioni delle prestazioni (e alcuni simpatici metodi extra, che ti consentono di ottenere il successivo bit impostato / non impostato).



Questa risposta suggerisce che ci sono ragioni significative per usare boolean [], ma come indicano i commenti, non c'è molto per sostenerlo. Detto questo: non programma molto in Java (e non ho nemmeno fornito alcuna prova;)
Matthew Schinckel

6

Ho letto che Java riserva un byte per un booleantipo di dati, ma utilizza solo un bit. Tuttavia, la documentazione dice che "la sua" dimensione "non è qualcosa che è definito con precisione" . Vedere qui.


Questo è un tutorial, non "la documentazione". La documentazione è JLS, JVM Spec. E Javadoc.
Marchese di Lorne

2

I booleanvalori vengono compilati nel inttipo di dati in JVM. Vedi qui .


2
Non è necessariamente così che vengono immagazzinati nella memoria, e penso che sia ciò che la persona che poneva la domanda voleva sapere. Quel documento descrive il formato del file di classe (codice byte compilato), non la rappresentazione di una variabile booleana in memoria, perché dipende dall'implementazione.
William Brendel

2

La dimensione del booleano in java dipende dalla macchina virtuale. ma qualsiasi oggetto Java è allineato a una granularità di 8 byte. Un booleano ha 8 byte di intestazione, più 1 byte di payload, per un totale di 9 byte di informazioni. La JVM quindi lo arrotonda per eccesso al successivo multiplo di 8. quindi l'unica istanza di java.lang.Boolean occupa 16 byte di memoria.


Tenderò a non essere d'accordo, su HotSpot JVM 1.7.0_51 l'intestazione ha 12 byte + 1 per il booleano + 3 per la granularità.
Eugene

14
non confondere Boolean con boolean.
andresp

1
Byte o bit? 16 byte per un mondo Booleansarebbe un tale spreco ... è la dimensione di un longche può trasportare trilioni di volte più informazioni di unBoolean
Dici

0

Non è definito; fare cose come suggerito da Jon Skeet ti darà un'approssimazione su una data piattaforma, ma il modo per sapere con precisione per una piattaforma specifica è usare un profiler.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.