Differenze tra le versioni di "C++ Garbage Collector"

Da Andreabont's Wiki.
(Compilare)
 
Riga 65: Riga 65:
 
Se necessario indicare il path dove trovare gli include necessari e la libreria condivisa.
 
Se necessario indicare il path dove trovare gli include necessari e la libreria condivisa.
 
<source lang="bash">
 
<source lang="bash">
g++ file.cpp -lgc -lgccpp [-I/path_install/include] [-L/path_install/lib64]
+
g++ file.cpp -lgc -lgccpp [-I/path_install/include] [-L/path_install/lib] [-Wl,-rpath,/path_install/lib]
 
</source>
 
</source>
  

Versione attuale delle 10:40, 29 gen 2020

Utilizzando l'apposita libreria garbage collector è possibile utilizzare in C++ un garbage collector conservativo. La stessa libreria può essere usata per cercare dei memory leak a run-time. Questo GC è di tipo conservativo ed implementa un algoritmo mark-sweep.

Integrazione con le classi C++

Il Boehm GC fornisce una comoda interfaccia a classi e una gestione degli operatori new e delete automatica che permette una facile integrazione con il C++. Il GC divide tra due tipi di allocazione:

  • Collezionabile: Questa zona di memoria verrà gestita direttamente dal GC, rimane possibile deallocarla manualmente.
  • Non-collezionabile: Questa zona di memoria non viene gestita, e rimane nella logica del C++ standard.

Segnalare una classe come collezionabile

Per dire al GC che una nostra classe deve essere gestita possiamo farla ereditare da due interfacce:

  • gc: Gesione base, dealloca direttamente.
  • gc_cleanup: Gestione che tiene conto dei distruttori, che vengono chiamati prima della deallocazione.

Modificatori dell'operatore new

Quando non abbiamo il controllo sulla classe, possiamo dire al GC di gestire o meno l'allocazione manipolando l'operatore new.

Allocare tramite il GC

Foo* bar = new (GC) Foo();

Allocare senza il GC

Foo* bar = new (NoGC) Foo();

Allocare con il GC usando un proprio distruttore

Foo* bar = ::new (GC, MyCleanup) Foo();

Esempio

#include <iostream>
#include <gc_cpp.h>

class Foo : public gc_cleanup {
public:

    int a[100000];
    
    // Costruttore
    Foo() {
        std::cout << "Creo Foo      [Ptr " << std::hex << this << "]\n";
    }
    
    // Distruttore
    ~Foo() {
        std::cout << "Distruggo Foo [Ptr " << std::hex << this << "]\n";
    }
};

int main() {

    for(int i = 0; i < 10; i++) {
        Foo* bar = new Foo();
    }

    GC_gcollect(); // Forzo intervento GC

}

Compilare

Se necessario indicare il path dove trovare gli include necessari e la libreria condivisa.

g++ file.cpp -lgc -lgccpp [-I/path_install/include] [-L/path_install/lib] [-Wl,-rpath,/path_install/lib]

Variabili d'ambiente

E' possibile ottenere modificare l'esecuzione impostando le seguenti variabili d'ambiente:

Statistiche

GC_PRINT_STATS=1 ./eseguibile         # Informazioni base
GC_PRINT_VERBOSE_STATS=1 ./eseguibile # Informazioni estese
GC_DUMP_REGULARLY=1 ./eseguibile      # Esegui dump durante l'esecuzione

Configurazione memoria

GC_INITIAL_HEAP_SIZE=10M ./eseguibile # Dimensione iniziale dell'heap
GC_MAXIMUM_HEAP_SIZE=10M ./eseguibile # Dimensione massima dell'heap

Altro

GC_DONT_GC=1 ./eseguibile             # Disabilita il garbage collector
GC_FIND_LEAK=1 ./eseguibile           # Esegue il programma segnalando i memory leak (non li gestisce!)