Qual é o tamanho de uma variável booleana em Java?


89

Qualquer um pode dizer o tamanho do bit de booleano em Java?


1
O mesmo é perguntado aqui: stackoverflow.com/questions/1907318/…
dma_k

Respostas:


41

Depende da máquina virtual.


9
Importa-se de apontar alguns documentos? Acho difícil acreditar que o tamanho de um booleano depende da máquina. Isso significaria que a representação binária de uma classe contendo um booleano teria tamanhos diferentes (e layouts de memória) em VMs diferentes e isso implicaria que as VMs não seriam compatíveis.
David Rodríguez - dribeas

14
Acho que ficou implícito que a questão se refere ao tamanho de uma variável booleana na memória, não ao tamanho de uma variável booleana codificada em um arquivo de classe. O tamanho da memória varia por VM de acordo com a documentação da Sun. O tamanho do arquivo de classe é constante.
William Brendel

3
@ DavidRodríguez-dribeas - O Sun JVM na época do Java 1.1 usava 4 bytes para booleano quando armazenado como uma instância ou var. Isso simplificou a implementação do interpretador de bytecode (que considera os bools como ocupando 4 bytes na pilha) e foi o caminho de menor resistência. Quando implementamos a JVM "Classic" do iSeries, encontramos maneiras de tornar a instância vars de 1 byte, pois isso melhorou muito a compactação de alguns objetos (o que tem um impacto incrível no desempenho). Aparentemente, com base nas postagens abaixo, os desenvolvedores da Sun / Oracle descobriram como fazer o mesmo nas versões posteriores.
Hot Licks

Mas está certo, no final de 2017 os JavaDocs dizem: boolean: The boolean data type... This data type represents one bit of information, but its "size" isn't something that's precisely defined- mas seu ponto é válido, ele poderia usar alguns links e informações melhores :)
JimLohse

185

Depende da máquina virtual, mas é fácil adaptar o código de uma pergunta semelhante perguntando sobre bytes em 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();
    }
}

Para reiterar, isso depende da VM, mas no meu laptop Windows executando o JDK da Sun build 1.6.0_11 obtive os seguintes resultados:

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

Isso sugere que os booleanos podem basicamente ser compactados em um byte pela JVM da Sun.


21
@skeet - Eu realmente o saúdo. sua resposta é incrível
Warrior

2
@warrior: Como eu já tinha o código para "byte", alterá-lo para "booleano" foi bastante simples :)
Jon Skeet

3
System.gc () não garante a limpeza da memória. Isso apenas dá uma ordem para a JVM executar a coleta de lixo, mas não significa que o coletor realmente limpou algo. Lembre-se de que o coletor limpa objetos NÃO USADOS. Um objeto não é usado se o programa não contém mais referências a ele. Portanto, em seu teste, eu eliminaria explicitamente a referência definindo LotsOfBooleans como null antes de executar gc (); OU apenas execute main uma vez com boolean, uma vez com int e compare os números.
Randa Sbeity,

2
@RandaSbeity Ou melhor: certifique-se de preservar as duas referências e calcular a diferença de memória. O que é exatamente o que acontece aqui.
biziclop

1
Existe alguma pergunta que Jon Skeet não possa responder?
Andreas Hartmann

31

As informações reais representadas por um valor booleano em Java são de um bit: 1 para verdadeiro, 0 para falso. No entanto, o tamanho real de uma variável booleana na memória não é definido com precisão pela especificação Java. Consulte Tipos de dados primitivos em Java .

O tipo de dados booleano possui apenas dois valores possíveis: verdadeiro e falso. Use este tipo de dados para sinalizadores simples que rastreiam condições verdadeiras / falsas. Este tipo de dados representa um bit de informação, mas seu "tamanho" não é algo definido com precisão.


21

Em uma nota lateral ...

Se você está pensando em usar um array de objetos booleanos, não o faça. Em vez disso, use um BitSet - ele tem algumas otimizações de desempenho (e alguns métodos extras interessantes, permitindo que você obtenha o próximo bit definido / não definido).


Isso nem sempre é verdadeiro stackoverflow.com/questions/605226/…
Przemek

Essa resposta sugere que há motivos significativos para usar booleano [], mas, como os comentários indicam, não há muito o que fazer. Dito isto: eu não
programo

6

Eu li que o Java reserva um byte para um booleantipo de dados, mas usa apenas um bit. No entanto, a documentação diz que "seu" tamanho "não é algo definido com precisão" . Veja aqui.


Isso é um tutorial, não 'a documentação'. A documentação é o JLS, JVM Spec. E Javadoc.
Marquês de Lorne

2

Os booleanvalores são compilados para o inttipo de dados na JVM. Veja aqui .


2
Não é necessariamente assim que eles são armazenados na memória, e acho que é isso que a pessoa que fez a pergunta queria saber. Esse documento descreve o formato do arquivo de classe (código de byte compilado), não a representação de uma variável booleana na memória, porque isso depende da implementação.
William Brendel

2

O tamanho do booleano em java depende da máquina virtual. mas qualquer objeto Java é alinhado a uma granularidade de 8 bytes. Um booleano tem 8 bytes de cabeçalho, mais 1 byte de carga útil, para um total de 9 bytes de informação. A JVM então o arredonda para o próximo múltiplo de 8. para que uma instância de java.lang.Boolean ocupe 16 bytes de memória.


Eu tenderei a discordar, no HotSpot JVM 1.7.0_51 o cabeçalho tem 12 bytes + 1 para o booleano + 3 para a granularidade.
Eugene de

14
não confunda booleano com booleano.
andresp

1
Bytes ou bits? 16 bytes por um Booleanseria um desperdício ... esse é o tamanho de um longque pode transportar trilhões de vezes mais informações do que umBoolean
Dici

0

É indefinido; fazer coisas como Jon Skeet sugeriu lhe dará uma aproximação em uma determinada plataforma, mas a maneira de saber precisamente para uma plataforma específica é usar um profiler.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.