In che modo le macchine virtuali allocano memoria?

1

Se desidero allocare un struct in C,

#include<stdio.h>

typedef struct container {
    int i;
} Container;

int main() {
    Container *ptr_to_container;

    ptr_to_container = (Container *) malloc(sizeof(Container));

    ptr_to_container->i = 10;

    printf("Container value: %d\n", ptr_to_container->i);

    free(ptr_one);

    return 0;
}

Devo chiamare esplicitamente malloc e free . Come fa una VM a fare questo?

Se creo un oggetto in Java,

public class Container {
    public int i;

    public static void main(String[] args) {
        Container container = new Container();
        container.i = 10;
        System.out.println("Container value: " + container.i);
    }
}

L'account Garbage Collectors per la liberazione, ma non l'allocazione. In che modo la JVM assegna la quantità di dati necessaria? Chiama malloc o un'altra implementazione di gestione della memoria?

In che modo la JVM conosce la quantità di dati necessari? Fa aumentare la lunghezza di tutti i campi?

    
posta phase 07.07.2016 - 02:21
fonte

2 risposte

4

How does the JVM allocate the amount of data needed?

Una macchina virtuale può usare malloc, ma probabilmente è una chiamata di sistema di livello inferiore.

Tuttavia, in genere allocano blocchi enormi e ritagliano singoli oggetti da quelli stessi anziché utilizzare 1 malloc o 1 chiamata di sistema per oggetto richiesto. I dettagli di come una grande porzione di memoria è stata ricavata in oggetti utilizzabili possono essere piuttosto complicati, ed è molto specifica per l'implementazione della macchina virtuale data, e in particolare per il garbage collector di tale implementazione. Può variare in base a molti fattori come il processore su cui è in esecuzione, ecc.

Il garbage collector è intimamente coinvolto in entrambe le allocazioni e nella liberazione della memoria; deve essere coinvolto nell'ordine di allocazione per fare un lavoro efficiente di liberazione. Spesso allocare memoria può essere semplice come far avanzare un puntatore attraverso uno di quei blocchi enormi che è gratuito.

Potresti leggere alcuni testi di Jones: Garbage Collection: Algoritmi per la gestione dinamica della memoria , o il più recente Manuale di raccolta dei rifiuti: l'arte della gestione automatica della memoria

How does the JVM know the amount of data needed? Does it add up the length of all the fields?

Una macchina virtuale sa quale quantità allocare per una data classe nello stesso modo in cui il compilatore C / C ++ sa come fare sizeof per una determinata struttura o classe. Sì, fino a un certo punto, si potrebbe dire che la macchina virtuale sommi i campi; tuttavia, più specificamente, è responsabile del posizionamento o della disposizione dei campi all'interno dell'oggetto (proprio come in C / C ++), in modo che la macchina virtuale conosca sia l'offset di ciascun campo sia la dimensione dell'intero oggetto. Entrambe le macchine virtuali e C / C ++ posizioneranno i campi con allineamento e riempimento secondo necessità per varie dimensioni dei campi e in base anche a considerazioni sull'allineamento della cpu.

    
risposta data 07.07.2016 - 02:47
fonte
1

@ErikEidt ha risposto a questa domanda per la domanda generale di VM nel suo insieme. Questa risposta descrive più dettagli specifici per la JVM Oracle (HotSpot).

La JVM non usa malloc o qualsiasi allocatore preesistente simile. Utilizza invece funzioni di sistema operativo di basso livello (ad esempio VirtualAlloc su Windows) per allocare un singolo blocco di indirizzi contigui di grandi dimensioni (la cui dimensione è modificata dal parametro della riga di comando -Xmx ) a cui verrà assegnata la memoria fisica e quando è necessario (vedere la risposta di thomasrutter a questa domanda per maggiori dettagli).

Quindi usa le proprie routine interne per suddividerlo come e quando necessario. In particolare, le allocazioni vengono eseguite in una sezione dello spazio indirizzo riservata agli oggetti appena allocati, in modo che per allocare lo spazio tutto ciò che JVM deve fare è prendere il valore di un puntatore e aggiungere la dimensione del nuovo assegnazione ad esso. Ciò rende veloce l'allocazione di oggetti in estremamente in JVM. Gli oggetti che non vengono raccolti rapidamente dal garbage collector vengono quindi spostati da questo spazio in uno spazio permanente gestito più tradizionalmente in un secondo momento (ma la maggior parte degli oggetti non dura abbastanza a lungo da farli accadere).

Per determinare la dimensione dell'allocazione, la JVM calcola la dimensione sommando le dimensioni dei campi (o i riferimenti ai campi se sono oggetti) e aggiungendo un sovraccarico per le cose che sono usate dalla VM stessa (memoria temporanea per il garbage collector, tabella dei metodi virtuali, ecc.). Questo calcolo viene eseguito una volta per ogni classe quando viene caricato e (almeno se viene utilizzato il metodo tipico di utilizzare new per creare l'oggetto) la dimensione viene memorizzata direttamente nel codice nativo per creare gli oggetti quando viene compilato a codice nativo. Gli oggetti creati tramite la riflessione potrebbero essere completamente diversi, non sono sicuro.

    
risposta data 07.07.2016 - 13:59
fonte

Leggi altre domande sui tag