[ Master Alucard @ 12.10.2007. 14:40 ] @
Da li itko zna kako smanjiti potrošnju resursa u programima napisanim pomoću Visual C++ /CLR

npr. napisao sam jedan program koji u principu treba da se pokreće sa Windows-om i koji će u toku rada čitati i pisati u XML file-ove, nešto malo u registry, itd.

Problem je taj što on troši oko 20 MB memorije u toku rada, to može da varira od 15 do 35 MB.
Što je očigledno previše za jedan program koji treba da radi non-stop.

Pitanje je, kako da smanjim potrošnju, odnosno gutanje te ogromne količine memorije na neki minimum?

Hvala unaprijed,
Master Alucard
[ Prokleta_Nedelja @ 13.10.2007. 22:18 ] @
zavisi šta si i kako napisao
[ bjevta @ 14.10.2007. 08:32 ] @
Tehnike koje koristim u C#:

1. pogledaj upotrebu "using". Naime, ako definišeš blokove koda tipa:

... neki kod pre ...
using(MyClass mc = new MyClass() )
{
... upotrebi "mc"
}
... neki kod posle ...

prostor koji je upotrebila promenjliva mc se odmah oslobađa.
Inače, ovo je zgodno i za trivijalne operacija, tipa setovanja wait mouse pointera prilikom dugih operacija.

2. GC.Collect(), posle operacija koje troše puno resursa

3. 35MB i nije previše za neki program. Dok ovo kucam, Firefox je zauzeo 70MB, RTDHCPL 22MB, samo VM Ware tray 18MB (sa ostalim rezidenting VM Ware programima skoro duplo više), FlashGet 10MB (ne skidam ništa u backgroundu), itd. Ako je ta aplikacija namenjena nečemu korisnom (nije neki seminarski i sl), jeftinije je dodati RAM nego se baktati sa optimizacijom.
[ mmix @ 14.10.2007. 10:25 ] @
1. using nema veze sa konzervacijom memorije, to je samo 'precica' za koriscenje disposable objekata (od uslovom da koriste iDisposable) i smanjuje kucanje koda, ne upotrebu memorije.

sledeca dva bloka su prilicno identicna:

Code:

using (X a = new X())
{
   a.nesto();
}


Code:

X a = new X();
try
{
   a.nesto();
}
finally
{
   a.Dispose();
}



2. Ovo je losa praksa, .NET runtime je savrseno sposoban da pozove odgovarajuci collect u optimalnom trenutku. Rucnim pozivanjem kreiras dva problema, prvi je da stalno forsiras GC da pretrazuje stablo objekata bez potrebe, drugi je da svaki preziveli objekat pri collectu bude promovisan u visu generaciju, tako da ce ti posle dva poziva colelct() svi zivi objekti zavrsiti u generaciji 2 i .net ih nece moci pocistiti dok ne zakljuci da mu je potrebno skupo ciscenje druge generacije sto moze da potraje i do kraja same aplikacije, samim tim ne da nisi smanjio memory footprint nego si ga samo povecao. Pogledaj ovaj blog u vezi situacija u kojima ima smisla pozivati collect(): http://blogs.msdn.com/ricom/archive/2003/12/02/40780.aspx

3. Ta memorija koju obojca gledate u task manageru se zove "working set", tj sva memorija koja je dodeljena procesu na koriscenje ukljucujuci i stranice koje nisu u samom RAMu. Alokacija working set-a je skuplji proces i windows tezi da aplikacijama da slobode i onda za njih neiskoriscene stranice drzi u virtuelnom modu i ne oduzima im working set dok bas ne zagusti (npr ako imas upaljeno vise procesa i minimizujes svoj prozor videces da ce pasti working set). Da vidite koliko zapravo memorije aplikacija ima alocirano morate da startujete perfmon i da pratite proces gledajuci "private bytes" merac.


Tako da samo opusteno, suma sumarum svih working setova svih aplikacija gotovu uvek prelazi velicinu fizickog rama, to jednostavno nije dobar pokazatelj potrosnje memorije.


To view your actual memory use perfmon and under process select private bytes
[ Master Alucard @ 14.10.2007. 22:44 ] @
Šta mislite o ovoj soluciji?

Nisam još nikako pokušavao napraviti "Windows Service" aplikaciju pa sam mislio da i to konačno uzmem ispred sebe i naučim uz ovaj primjer.

Znači da napravim dvije aplikacije: jedna ista kao i prije, radi sve ono što je potrebno, a druga (Windows Service) će sama da radi u pozadini i samo po potrebi pokrećati onu "Work" aplikaciju.

Ona "Work" aplikacija ne radi ništa drugo nego da snima neke podatke u XML file-ove, tako da ona u principu nemora da radi non-stop, ali mi je ipak potrebno da su ti podaci stalno prisutni, tako da mora da radi non-stop. Sa ovim scenariom bi to rješio.

Pošto ona pokreće neku drugu aplikaciju po potrebi, nebi trebala da troši toliko memorije.

ili ne ... ?