Kayıt: Aug 04, 2005 Mesajlar: 173 Nereden: Vault 35
Tarih: Thu Sep 22, 2005 7:31 am Mesaj konusu: Disposing
Uğraşmakta olduğum oyun kodunda(c#) bi sorunum var umarım yardımlarınızla çözüme kavuşur.Kodda birimler 200 lük bir sınıf arrayinde tutuluyor (birim[200]) ve 200 birim yaklaşık 5-6 mb yer tutuyor;
birimi şöyle ekliyorum {birimno++;birim[birimno]=new birim();.....}
birim ölüncede siliyorum {birim[birimno]=null;birimno--;}
olay şuki ben birim ekleyip öldürdükçe oyun şişiyor ve doğal olarak yavaşlıyor , biraz kitap karıştırdım dispose olayını denedim , Garbage collectorı çağırdım yine bi sonuş alamadım.Sanırım ben "new birim()" dedikçe program farklı bir adrese gidiyor ve şişme oluyor ama neden memoryi boşaltamıyorum,program null atadığım yerleri neden bırakmıyor, pointerla stackalloc fln kullansam olur mu , önerilerinizi bekliyorum , şimdiden teşekkürler
Kayıt: Aug 04, 2005 Mesajlar: 173 Nereden: Vault 35
Tarih: Tue Sep 27, 2005 11:20 pm Mesaj konusu:
Aynstaynx dediğin şekilde yapmam grafik motoru nedeniyle mümkün olmuyo , arkadaşlar cidden bilgisi olan varsa bi fikir versin , hocalara sordum linked list kullan o zaman dispose edersin fln dediler kodu baştan aşşa linked liste çevirdim oda olmadı , walla yalan olcak bizim oyun böyle
Kayıt: Apr 24, 2003 Mesajlar: 287 Nereden: İstanbul
Tarih: Wed Sep 28, 2005 8:24 am Mesaj konusu:
programında başka yerlerde de o elemana referanslar tutuyorsan, o alanları garbage collector temizlemez.
örneğin, her elemanın en yakınındaki elemanı da bir member array olarak tutuyorsan böyle bişeyler le karşılaşabilirsin:
Kod:
class DusmanElemanlar
{
// kendine en ykain 10 tanesi de burda duruyo mesela
DusmanElemanlar enYakin[ 10 ] ;
... bla bla bla...
}
// biryerlerde de bu var mesela
DusmanElemanlar[ ] tumDusmanlar = new DusmanElemanlar[200] ;
işte, eğer yukarıdaki 10 luk arrayde de senin 200 lük arraydaki elemanlara referanslar tutuyorsan, o alanlar boşaltılmaz.
Bu direk referans olmak zorunda da değil. ArrayList, Vector, Hashtable, Map vs. gibi collection ları da kullandığında aynı kapıya çıkar. Temizlenmesi için tüm referanslarını silmelisin.
bir ihtimal de şu: Java da soft/weak referance diye birşeyler var. eğer bir class a başka normal referans yoksa garbage collector un o elemanı silmesine izin veriyor. c#dada benzer bir yapı varsa ve 200 lük arrayın dışında sadece bu tür referansları kullanırsan, böyle şeylerle başın ağrımaz.
Bir pointer'a NULL atamak o pointer'ın tutuğu bellek alanını bırakması anlamına gelmez! (Dinamik bellek alanı ise) Nasıl bellek alanı ayırdıysan örn: New(); aynı şekilde dilin kendi bellek bırakma fonksiyonunu kullanmak gerek örn: Delete(), bu işlemden sonra NULL atayacaksın... Şişmesinin nedeni bu olabilir, çünkü: aldığın alanların hiç birini bırakmıyorsun, işte bu yüzden programın şişiyor...
Yaptığın işlem:
yapi *isaretci = 0;
isaretci = New(); // Sistem sana bellekte bir yer tahsis ediyor ve bunun adresini geri döndürüyor...
isaretci = NULL; // Sadece işaretçiye NULL yani 0 atamış oluyorsun ama bellek alanı hala duruyor. Bundan önce aşağıdakini yapman gerek!
Delete(isaretci);
Bir pointer'a NULL atamak o pointer'ın tutuğu bellek alanını bırakması anlamına gelmez! (Dinamik bellek alanı ise) Nasıl bellek alanı ayırdıysan örn: New(); aynı şekilde dilin kendi bellek bırakma fonksiyonunu kullanmak gerek örn: Delete(), bu işlemden sonra NULL atayacaksın... Şişmesinin nedeni bu olabilir, çünkü: aldığın alanların hiç birini bırakmıyorsun, işte bu yüzden programın şişiyor...
Yaptığın işlem:
yapi *isaretci = 0;
isaretci = New(); // Sistem sana bellekte bir yer tahsis ediyor ve bunun adresini geri döndürüyor...
isaretci = NULL; // Sadece işaretçiye NULL yani 0 atamış oluyorsun ama bellek alanı hala duruyor. Bundan önce aşağıdakini yapman gerek!
Delete(isaretci);
C# dan pek anlamam, ama Java ya benzediğini biliyorum. Ve eğer aynı mantıkla çalışıyorlarsa eğer, bu dillerde Delete diye bir komut yok. bu işi bizim yerimize Garbage Collector denilen bir alet otomatik yapıyor. Tabii önce Delete etmesinin güvenli olduğundan emin olmaya çalışıyor. Eğer new dediğin bir yere hiç referans kalmadıysa, orayı kendisi delete ediyor. NULL a set ettiğinde, referans kalkmış oluyor. ve Garbage Collector o adresi claim edebiliyor. Ama o adrese birden fazla gösterge varsa, biz birini NULLa set etsek bile, garbage collector orayı delete edemiyor.
Kayıt: Aug 04, 2005 Mesajlar: 173 Nereden: Vault 35
Tarih: Thu Sep 29, 2005 11:57 am Mesaj konusu:
denemelerim sonucunda gördüm ki garbage collector bir arrayin içine erişemiyor yani arrayin herhangi br elemanın null atamak ve GC yi çağırmak hiç bir işe yaramıyor,daha sonra bende arraylist denen yapıyı kullandım bunda başarılı olma şansız var ama bundada bir türlü arraylistdeki elemanın kendisini null atayamıyorum ancak şöyle birşey oluyor liste[i]=null diyince listenini "i" indexini null atıyorum daha önce "i" indexinin kaplayan elemanı null atamış olmuyorum ki bu eleman yer tutmaya devam ediyor,arraylist in içindeki elemana direkt ulaşmanın bir yolu varsa bu olayı çözecek gibi ama yoksa sanırım yapacak tek şey unsafe modda pointer kullanmak olacak
Kayıt: Apr 24, 2003 Mesajlar: 287 Nereden: İstanbul
Tarih: Thu Sep 29, 2005 12:45 pm Mesaj konusu:
DarkScythe demiş ki:
denemelerim sonucunda gördüm ki garbage collector bir arrayin içine erişemiyor yani arrayin herhangi br elemanın null atamak ve GC yi çağırmak hiç bir işe yaramıyor
Garbage collector un array içine erişememesi imkansız. Array denilen şeyler, Java ve C# da Object in boyu * array size kadar olan memory alanları değildir. Sadece Array Size kadar pointer lardan oluşur. Ve sen her elemanı new diyerek set etmezsen, direk null pointer exception alırsın. çünkü O elemanlara ait memory henüz ayrılmamış oluyor.
ArrayList denilen alet de aslında içinde bi Array kullanıyor. Bu yüzden onu kullanman ile normal array arasında hiç bir fark yok.
GC yi çağırdıktan sonra değişiklik olmaması için olası nedenler:
Kod:
Object [] array = new Object[20000] ;
dedik, X kadar boş. sonra
array[100] = null ;
dedik mesela ve tekrar baktık. değişim yok. çünkü zaten array in elemanlarına tek tek new Object atmadık.
Diyelim o şekilde new yaptık tekrar denedik, yine olmadı.
Şu yüzden olabilir: Java da GC arkaplanda kendi kendine çalışır ve bulduğu boştaki nesneleri temizler. Ama sen null der demez GC bunu temizleyemeyebilir. Henüz invoke edilmemiş olabilir. vs. vs. Eğer C# da da bu şekildeyse, null der demez free etmeyebilir.
Üçüncü ve önceki mesajımda bahsettiğim olayda şu: O new dediğimiz objeye başka referanslar da olabilir. Örnek:
yukarıda, o2 hala daha ayırdığımız objeyi gösterdiği için GC temizlemez.
en son ihtimal de şu:
Java da da GCde bir bug vardı. Belki bir şekilde hasbel kader c# ın GC bugını bulmuş olabilirsin. Ama bunun ihtimali 10 üzeri eksi 200 den falan küçüktür. o yüzden, bu ihtimal yok sayabilirsin
Bu forumda yeni konular açamazsınız Bu forumdaki mesajlara cevap veremezsiniz Bu forumdaki mesajlarınızı değiştiremezsiniz Bu forumdaki mesajlarınızı silemezsiniz Bu forumdaki anketlerde oy kullanamazsınız