56 votes

Taille d'un octet en mémoire - Java

J'ai entendu des avis partagés sur la quantité de mémoire qu'un octet prend place dans un programme java.

Je suis conscient que vous pouvez stocker pas plus de +127 en java, et la documentation dit qu'un octet est à seulement 8 bits, mais ici je me suis dit qu'en fait, il utilise la même quantité de la mémoire comme un int, et, par conséquent, est juste un Type qui aide dans le code de la compréhension et de ne pas l'efficacité.

Quelqu'un peut-il éclaircir ce point, et serait-ce une mise en œuvre spécifique de l'enjeu?

67voto

Jon Skeet Points 692016

Ok, il y a eu beaucoup de discussions et pas beaucoup de code :)

Voici un rapide benchmark. Il a la normale mises en garde quand il s'agit de ce genre de chose - test de la mémoire a des bizarreries en raison de JITting etc, mais avec suffisamment de grands nombres, il est utile de toute façon. Il dispose de deux types, chacun avec 80 membres - LotsOfBytes a 80 octets, LotsOfInts a 80 ints. Nous construisons beaucoup d'entre eux, assurez-vous qu'ils ne sont pas GC souhaitez, et de vérifier l'utilisation de la mémoire:

class LotsOfBytes
{
    byte a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
    byte b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
    byte c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
    byte d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
    byte 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
    {        
        LotsOfBytes[] first = new LotsOfBytes[SIZE];
        LotsOfInts[] second = new LotsOfInts[SIZE];

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

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

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

        System.out.println ("Size for LotsOfBytes: " + (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 + second[i].a0;
        }
        System.out.println(total);
    }

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

Sortie sur ma boîte:

Size for LotsOfBytes: 88811688
Average size: 88.811688
Size for LotsOfInts: 327076360
Average size: 327.07636
0

Alors, évidemment, il y a certains frais généraux - 8 octets par les regards de celui-ci, bien que d'une certaine manière seulement 7 pour LotsOfInts (? comme je l'ai dit, il y a des bizarreries ici) - mais le point est que les octets des champs semblent être emballé pour LotsOfBytes telle qu'il faut (après suppression des frais généraux), seulement un quart de la quantité de mémoire LotsOfInts.

20voto

Mecki Points 35351

Oui, une variable d'octet est en fait de 4 octets en mémoire. Cependant, cela ne vaut pas pour les tableaux. Un tableau d'octets de 20 octets ne représente en réalité que 20 octets en mémoire. En effet, le langage Java Bytecode Language ne connaît que les entrées et les longues comme types de nombres (il doit donc gérer tous les nombres comme types, 4 octets ou 8 octets), mais il connaît les tableaux avec toutes les tailles de nombres possibles (les tableaux sont donc courts). fait, deux octets par entrée et les tableaux d’octets sont en fait d’un octet par entrée).

7voto

Bill the Lizard Points 147311

Java n'est jamais mise en œuvre ou de plate-forme spécifique (au moins autant que de type primitif tailles sont concernées). Ils les types primitifs sont la garantie de toujours rester le même, quelle que soit la plateforme que vous utilisez. Ce qui diffère de l' (et a été considérée comme une amélioration sur) C et C++, où quelques-uns des types primitifs ont été la plate-forme.

Depuis c'est plus rapide pour le système d'exploitation à l'adresse de quatre (ou huit, dans un système 64 bits) octets à la fois, la JVM peut allouer plus d'octets pour stocker une primitive d'octets, mais vous pouvez toujours stocker des valeurs allant de -128 à 127.

5voto

izb Points 12736

Un exercice révélateur consiste à exécuter javap sur un code qui fait des choses simples avec des octets et des ints. Vous verrez des bytecodes qui attendent des paramètres int fonctionnant sur des octets, et des bytecodes insérés pour co-erceer de l'un à l'autre.

Notez cependant que les tableaux d'octets ne sont pas stockés en tant que tableaux de valeurs sur 4 octets. Par conséquent, un tableau d'octets de 1024 longueurs utilisera 1k de mémoire (en ignorant les temps système).

3voto

Jon Skeet Points 692016

Cela dépend de la manière dont la machine virtuelle Java applique le remplissage, etc. Un tableau d'octets (dans n'importe quel système sain) est compressé dans un octet par élément, mais une classe avec quatre champs d'octets peut être soit compactée, soit complétée par des limites de mots - cela dépend de la mise en œuvre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X