Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Garbage Collection

E' un pò che cerco informazioni su come gestire da programma
la Garbage Collection di VB.
Ho sviluppato in VB un programma che fà intenso uso della
programmazione ad oggetti (per quello che si può in VB) ed
ho un problema:
Ho implementato una classe che implementa una sorta di Nodo di una rete.
Ogni nodo contiene due collection di altri Nodi:
    una collection di nodi "Parent"
    una collection di nodi "Child"
la struttura è tale da poter generare dei "cicli" cioè scorrendo da nodo a
nodo è possibile
che dopo un pò di "giri" si ritorni al nodo di partenza.
Fino a questo punto tutto bene!
Nella creazione della struttura non ci sono particolari problemi, i problemi
appaiono quando devo "distruggere" la struttura (magari per ricrearne una
nuova):
                    VB ci mette un sacco di tempo !!!!!!
(alcuni minuti su un Pentium 350 con 128 MB di RAM e NT Workstation).
Ho controllato con il monito di sistema di NT ed ho scoperto che VB libera
la memoria molto lentamente.
Secondo me a causa della Garbage!!!!
Qualcuno mi dice se è possibile distruggere gli oggetti quando e come decido
io e non quando e come decide la Garbage?
Se qualcuno ha delle informazioni a riguardo e ha voglia di postarle
aiuterebbe VB a guadagnare punti.
L'alternativa è di utilizzare delle classi C++ ma perderei un cliente che
vuole VB
perchè avrebbe la possibilità di potersi modificare facilmente il codice.
Grazie per le eventuali risposte.
            A presto.
 punti altrimenti sarnella mia azienda altrimenti sarò costretto ad
utilizzare in C++ (come dire un cannone per una mosca)




Altro cliente sfigato che conosce VB perche' la segretaria usa Excel...
Ti capisco!!!
--
Roal Zanazzi
z...@iol.it

le collection vengono gestite in modo simile agli array dinamici.
Qui posso intervenire io ^__^ ....
Le collection sono implementate internamente come liste concatenate doppie
con ulteriori caratteristiche per permetterne l'indicizzazione. Questa
struttura velocizza l'accesso agli elementi che si trovano all'inizio ed
alla fine della collection, ma penalizza l'accesso agli elementi che si
trovano in mezzo. Per collection piccole la differenza di velocità è
trascurabile, ma su quelle grandi occorre fare attenzione e per quanto
possibile evitare di inserire o eliminare elementi che stanno nel bel mezzo
della collection se si vuole avere un programma scattante.
Zeross


Grazie di nuovo


Probabilmente la scelta dei proggettisti è stata di privilegiare il
meccanismo di For Each penalizzando l'accesso random.
Ho nostalgia dei contenitori e degli iteratori della Libreria Standard del
C++ (STL)!
Ciao
Salvatore

le mani!
Appunto, gliel'ha detto la segretaria (che di metterci le mani se ne intende
;-)
--
Roal Zanazzi
z...@iol.it

la memoria molto lentamente.
Potresti implementare la gestione di questa struttura dati dentro ad
un EXE ActiveX da richiamare da parte del programma che gestisce
l'interfaccia utente. L'uso di un EXE ActiveX permette di avere una
esecuzione asincrona: il front-end e l'EXE ActiveX vengono eseguiti
indipendentemente l'uno dall'altro.
Strutturando bene il tutto dovrebbe essere possibile attivare il
modulo esterno che gestisce le collection e aspettare che questo
restituisca i dati elaborati da presentare. A questo punto il
front-end presenta i dati mentre l'EXE ActiveX dealloca la memoria
senza bloccare il front-end.
L'unico problema č che non puoi ripetere l'elaborazione prima che sia
terminata la deallocazione, ma non dovrebbe essere terribile.
Ciao
--------------------------------------------------------------------
Fulvio Senore
Eliminate "zz" dall'indirizzo e-mail per scrivermi (spammers...)
Remove "zz" from e-mail address to write me (spammers...)
--------------------------------------------------------------------

La soluzione di visualizzare i dati e poi distruggere la struttura ha lo
stesso effetto:
L'utente si trova a non poter fare niente davanti la finestra dei risultati
(scorrere etc..)
L'idea dell'ActiveX l'ho sperimentata ma ha lo stesso effetto, il processo
della
Garbage "ammazza" il processore, l'unica cosa che si riesce a fare è far
partire
Explorer (forse ha una priorità maggiore di esecuzione) ma anche lui gira
lentamente!
Comunque grazie per i suggerimenti, se ne avete altri sono i benvenuti!
Oramai mi sono dedicato ad altri aspetti del programma in attesa che
vi venga l'idea giusta o che qualcuno di buon cuore (ed esperienza ;-))) mi
dia
la dritta.
Riposterò il quesito tra qualche tempo quando non potrò più rimandare la
cosa!
Grazie di cuore a tutti, è molto che leggo in NG ma intervengo poco o per
ignoranza
o perchè ho soluzioni peggiori di quelle che hanno  gli altri.
A presto
Salvatore


Ellllllaaaamiseriaaaaaaaa.....
Ma quanti terabyte di memoria allochi?????
Su che PC l'hai provato? Quanta RAM?
Swappa su disco durante la deallocazione?
E, ripeto, dato che non mi hai risposto: come distruggi la struttura? Con
quali istruzioni?
--
Roal Zanazzi
z...@iol.it


E' vero sono stato un pò vago nella descrizione, spiego meglio cosa devo
fare:
Supponi di dover interpretare dei "messaggi" ognuno dei quali ha un'insieme
di record (nel problema si chiamano "segmenti") ognuno di questi "record" è
costituito da un certo numero di campi ("tag" nel problema) i record di un
messaggio non sono tutti uguali ma sono identificati dal tipo (possono
essere un centinaio) ogni "tipo record" ha una struttura differente
(differenti tag sia nel numero che nella disposizione).
I segmenti del messaggio hanno un livello di appartenenza nel senso che il
messaggio contiene segmenti al livello 1,
i segmenti al livello 1 contengono riferimenti ad altri segmenti diciamo al
livello 2,
i segmenti a livello 2 contengono riferimenti ad altri  segmenti a livello 3
ma possono contenere anche riferimenti ai segmenti del livello 1
come vedi un bel casino!
In pratica si tratta di un sistema di interpretazione dei messaggi EDI
(Electronic Data Interchange) che è poi il sistema con cui le grandi aziende
manufatturiere (FIAT etc.) si scambiano gli ordini, le fatture, le bolle di
consegna etc. attraverso la rete X.25.
A questo punto ho progettato il sistema con una serie di oggetti:
(partendo dal basso e semplificando di molto la cosa)
CTag               : la classe che contiene la definizione del tag (campo)
ed il contenuto
CSegmento    : la classe che contiene i dati del segmento
                            una Collection di CTag,
                            una Collection di CSegmento (i "Parent")
                            una Collection di CSegmento (i "Child")
CMessaggio  : la classe che contiene i dati generali del messaggio e una
Collection di
                            CSegmeto
Durante l'esecuzione si devono memorizzare un certo numero di CMessaggio
per cui ho una Collection di CMessaggio.
I dati per riempire la struttura sono su file di testo,
la definizione dei messaggi, segmenti e tag sono su database
(è una definizione statica ma li ho messi su DB per poterli gestire
facilmente)
Non memorizzo nessun dato su DB
Alcune decine di Messaggi con qualche centinaio di segmenti con qualche
decina di tag per ogni segmento.
Serve abbastanza memoria ma non troppo, ho controllato che a pieno regime la
struttura alloca circa 200-300 MB.
Il problema è alla distruzione della collection dei messaggi, ho provato
varie strade:
-    Le Collection impostate a Nothing: prima tutta la collection principale
poi tutte le collection a partire dalle più "basse"
-    Le Collection deallocate in ordine diretto/inverso di creazione (sempre
a partire dal basso)
-    La struttura su ActiveX sia DLL che EXE.
Il risultato è sempre lo stesso per quanto riguarda i primi due metodi,
mentre è un pò diverso per gli ultimi due.
Nei primi due casi il programma non restituisce il controllo per molto tempo
e appena restituito il
controllo continua ad essere lentissimo per altro tempo (parlo di MINUTI).
Nei secondi due casi il programma ritorna il controllo più in fretta ma per
molto tempo rimane lentissimo!
Il PC che utilizzo è un 350MHz con 128 MB di RAM con NT Workstation.
Ho provato sia con VB5 che con VB6.
Attraverso il Task manager di NT è possibile vedere
l'andamento del processore e della memoria
durante il "fattaccio" il processore è perennemente al 100% e
la memoria da 200-300 MB scende lentissimamente verso
i 40-50 MB di normale allocazione.
Durante questo tempo il programma non risponde neanche al Repaint,
gli altri programmi girano lentamente
l'unico che un pò di brio è Explorer che (anche se non come a vuoto)
mi permette di "sfogliare" le directory.
Spero di essere stato chiaro comunque grazie moltissimo dell'interessamento.
Secondo una mia personale diagnosi è che qualche la DLL di sistema di VB
La mia diagnosi è che qualche DLL di sistema di VB (Msvbvm60.dll?)
vada in crisi e non risponda alle altre chiamate
se non quando la Garbage finisce il lavoro.
E dire cha la Garbage dovrebbe girare con
priorità bassissima e nei tempi si vuoto di elaborazione!!
Comunque grazie di nuovo a tutti per la disponibilità.
--
            ^^^^^^                                              Ciao
              (,) (,)
---o000--------000o---------------------------
 \_\_    \_    \_     \_        \_           \_
   \_  \_  \_    \_   \_   \_  \_   \_     \_
     \_ \_   \_    \_  \_         \_            \_
       \_        \_   \_    \_   \_  \_   \_    \_
         \_         \_\_         \_         \_       \_
        e-mail 
ppu...@programmer.net
 
ppu...@cimabue.polito.it
-----------------------------------------------------
(togliere la doppia p per la risposta)


Grazie del suggerimento, ho gią sperimentato, il problema secondo me non č
nel programma ma in qualche DLL di VB (Msvbvm60.dll?) che essendo "da sola"
a rispondere alle applicazioni VB genera il problema.
Comunque grazie č il modo migliore provato fin'ora.


gia'...dovrebbe... e "dovrebbe" anche essere in un altro thread, ma non si
puo' chiedere miracoli alla M$ (spesso non riesce a fare nemmeno le cose
"normali"...)
--
Roal Zanazzi
z...@iol.it


Se ci sono soldi potresti anche usare l'edizione Enterprise di VB e
sistemare l'EXE ActiveX su un'altra macchina collegata in rete. In
questo modo il rallentamento si produrrebbe sull'altra macchina.
Con NT potresti anche provare con una macchina con due processori. Con
un po' di fortuna la deallocazione dovrebbe ammazzare solo uno dei
processori.
