Spero che tu ti renda conto che tutto questo è profondamente definito dall'implementazione, sia per Java che per C ++. Detto questo, il modello a oggetti di Java richiede un bel po 'di spazio.
Gli oggetti C ++ non hanno (generalmente) bisogno di qualsiasi storage tranne per quello di cui i membri hanno bisogno. Si noti che (a differenza di Java, dove tutto è definito dall'utente come un tipo di riferimento), il codice client può utilizzare un oggetto sia come tipo di valore che come tipi di riferimento, ovvero un oggetto può memorizzare un puntatore / riferimento a un altro oggetto o archiviare direttamente l'oggetto senza indirezione. Un puntatore aggiuntivo per oggetto è necessario se ci sono metodi virtual
, ma alcune classi utili sono progettate per andare avanti senza polimorfismo e non ne hanno bisogno. Non ci sono metadati GC e nessun blocco per oggetto. Pertanto gli oggetti class IntWrapper { int x; public: IntWrapper(int); ... };
non hanno bisogno di più spazio di int
s, e possono essere posizionati direttamente (cioè senza riferimento indiretto) in raccolte e altri oggetti.
Gli array sono complicati semplicemente perché non esiste un equivalente comune, preimpostato, di un array Java in C ++. Potresti semplicemente allocare un gruppo di oggetti con new[]
(senza alcun overhead / metadata) ma non c'è un campo lunghezza - l'implementazione probabilmente ne memorizza uno ma non puoi accedervi. std::vector
è un array dinamico e quindi ha un overhead aggiuntivo e un'interfaccia più grande. std::array
e array in stile C ( int arr[N];
), hanno bisogno di una costante in fase di compilazione. In teoria, dovrebbe essere solo lo spazio di archiviazione dell'oggetto più un singolo intero per la lunghezza, ma dal momento che è possibile ottenere il ridimensionamento dinamico e un'interfaccia completa con pochissimo spazio in più, in pratica basta fare questo. Si noti che tutte queste, insieme a tutte le altre raccolte, hanno come impostazione predefinita la memorizzazione degli oggetti in base al valore, salvando in tal modo il riferimento indiretto e lo spazio per i riferimenti e il miglioramento del comportamento della cache. È necessario archiviare esplicitamente i puntatori (quelli intelligenti, per favore) per ottenere l'indirezione.
I confronti sopra riportati non sono del tutto equi, poiché alcuni di questi risparmi sono garantiti non includendo le funzionalità Java include, e il loro equivalente C ++ è spesso meno ottimizzato rispetto all'equivalente Java (*). Il modo comune per implementare virtual
in C ++ impone un sovraccarico tanto quanto il modo comune di implementare virtual
in Java. Per ottenere un blocco, è necessario un oggetto mutex con funzioni complete, che è probabilmente più grande di alcuni bit. Per ottenere il conteggio dei riferimenti ( non equivalente a GC e non dovrebbe essere usato come tale, ma a volte utile), è necessario un puntatore intelligente che aggiunge un campo di conteggio dei riferimenti. A meno che l'oggetto non sia costruito con cura, il conteggio dei riferimenti, l'oggetto puntatore intelligente e l'oggetto referenziato si trovano in posizioni completamente separate e, anche quando lo si costruisce correttamente, il puntatore condiviso può essere (necessario?) Due puntatori invece di uno. Inoltre, un buon stile C ++ non usa queste caratteristiche abbastanza per essere importante - in pratica, gli oggetti di una libreria C ++ ben scritti usano meno. Ciò non significa che necessariamente significhi un minor utilizzo di memoria in generale, ma ciò significa che C ++ ha un buon vantaggio in questo senso.
(*) Ad esempio, è possibile ottenere chiamate virtuali, codici hash di identità e blocco con una sola parola per alcuni oggetti (e due parole per molti altri oggetti) unendo le informazioni sul tipo con vari flag e rimuovendo i bit di blocco per oggetti che improbabilmente necessitano di serrature. Vedi Implementazione efficiente in termini di spazio e tempo del modello a oggetti Java (PDF) di David F. Bacon, Stephen J. Fink e David Grove per una spiegazione dettagliata di questa e altre ottimizzazioni.