Uygulamamızın kullandığı hafıza miktarını nasıl düşürebiliriz
Transkript
Uygulamamızın kullandığı hafıza miktarını nasıl düşürebiliriz
Contact Me | Subscribe D e l p h i P r o g r a m m i n g Search Keywords There are only 10 types of people in the world: Those who understand binary, and those who don’t. Home TObject.Create Delphi Hakkında Ziyaretçi Defteri Posted by Tuğrul HELVACI - Mayıs 16, 2009 Comments 2 Uygulamamızın kullandığı hafıza miktarını nasıl düşürebiliriz ? Hepimizin bildiği gibi yazdığımız uygulamalar işletim sisteminde Process olarak adlandırılmaktadır. Her bir process en az bir main thread’e sahiptir. Bu iş parçacıkları, derlenmiş ikilik formattaki ham bilginin işletim sisteminin bellek yöneticisi vasıtası ile hafızaya yüklenerek işletilmesi ile hayat bulur. İşletim sistemlerinin bellek yönetimini nasıl yaptıkları son derece karmaşık bir konudur. Bir işletim sisteminde aynı anda birden fazla iş parçacığının çalışabilme ihtimali olduğu için bu işlemlerin bellekte kaplayacakları alanların ve bu bellek bölgeleri arasındaki etkileşimlerin son derece dikkatle hesaplanması gerekmektedir. İşletim sistemlerinde bir process fiziksel bellek ile iletişim halinde değildir. Bunun yerine her bir iş parçacığı için ayrılmış olan hafıza bloklarında her bir işlem kendisini fiziksel belleğin hakimi sanmaktadır. Bu tasarım, her bir işlem parçacığının teoride fiziksel belleğin kendisinden de daha fazla hafıza bloğuna sahip olabilmesini sağlamaktadır. Tüm bunları detaylıca anlatacak ne yerim ne de yeterince malümatım var ancak, bildiklerim ışığında izah etmeye devam edeyim. Process’lerin yani iş parçacıklarının fiziksel bellekten daha fazla alan kullanabilmesine imkan tanıyan teorik yaklaşıma Virtual Memory adı verilir. Virtual Memory modern işletim sistemlerinde disk vb. depolama cihazlarının kapasitelerinin bir kısmının fiziksel Plugin WP FlashTime by horoscop 2009.org requires Flash Player 8 or better currency converter calculator.Plugin creat de horoscop | horoscop saptamanal | horoscop zilic | horoscop | play sonic games Etiketler Absolute Abstract Classes ActionScript Algoritma API Bug Byte Arrays Class Reference CloseHandle COM CreateDesktop CreateEvent CreateMutex CreateProcess CreateRemoteThread CreateSemaphore CreateToolHelp32SnapShot CreateWaitableTimer DeleteCriticalSection delphi 2010 DTS EnterCriticalSection PDFmyURL.com modern işletim sistemlerinde disk vb. depolama cihazlarının kapasitelerinin bir kısmının fiziksel hafıza alanı gibi kullanması anlamına gelir. Örneğin Windows işletim sistemlerinde bu pagefile.sys dosyasıdır. İşletim sistemi bir iş parçacığının çalışması için gerekecek hafıza bloğunun karşılanamaması durumunda disk üzerindeki bahsi geçen dosyayı bir hafıza alanı gibi kullanarak fiziksel hafıza alanını rahatlatmaya çalışmaktadır. Ancak RAM’de tutulamayan verilerin sürekli disk ve RAM arasında yazılıp okunması elbette iş parçacığının çalışma performansını olumsuz yönde etkiler. İşletim sistemleri, RAM ile sanal bellek arasındaki adreslemeleri fiziksel bellek haritasını kullanarak gerçekleştirirler. Her bir işlem için ayrılmış izole hafıza bloğundaki $101112 gibi bir adres fiziksel adresteki aynı adres demek değildir. Bu adresin fiziksel adresteki karşılığı başka bir tabloda tutulur ve fiziksel hafızaya erişim için bu tablodan istifade edilir. Modern işletim sistemleri, iş parçacıkları için ayırdıkları hafıza bloklarının tamamen izole olmasından sorumludurlar. Bir iş parçacığının diğer birisinin kullandığı hafıza bloğuna erişimi, o blokta yapabileceği değişiklikler tehlikeli durumlara sebebiyet verecektir. İşte bu sebeple arada sırada da olsa Protection Fault gibi hatalar alırız. Aynı zamanda işletim sistemleri, mevcut fiziksel hafızayı iş parçacıkları üzerinde adil dağıtma gibi bir misyonu da bünyelerinde barındırmak durumundadırlar. Tüm bu karmaşık hususların gerçekleştirilebilmesi adına işletim sistemleri iş parçacıkları için onların kullanacakları reel hafızadan daha fazlasını ayırmak durumundadırlar. İşletim sistemleri paging adı verilen bu hafıza tahsisinde belli bloklarla hafıza rezerve edeceklerdir. Ayrılan hafıza bloklarınında ardışıl olmaması gibi sorunları da kendi içinde çözmesi gereken işletim sisteminin işinin ne kadar karmaşık ve kompleks olduğunu anladık sanırım. Tüm bu genel kültürel bilgilerin ışığında, hepimizin farkettiği gibi yazmış olduğumuz uygulamalar işletim sisteminin bellek yöneticisi vasıtası ile hafızaya alındığında belli bir çalışma alanına sahip olur(Working Size). Bu çalışma alanı, uygulamamız içinde kullandığımız nesneler, değişkenler, threadler ile giderek daha da artabilir. Hatırlarsanız işletim sisteminin hafıza ayırma işlemini paging adı verilen karmaşık bir mekanizma ile yaptığını anlatmıştım. Bu mekanizma da işletim sistemi sizin gerçekte ayırmak istediğiniz hafıza bloğu 50k olsa bile her bir page size ne kadar ise o kadar ayıracaktır. Diyelim ki sizin ayırmak istediğiniz hafıza bloğu 40 kb ve page size’ında 100 kb olması durumunda, sizin bu işleminiz karşısında işletim sistemi 40 kb değil 100 kb yer ayıracaktır. Bu durumda sizin istemediğiniz 60 kb lık bir açık oluşacaktır! Programlarınızın uzun süreçlerde hiç kapanmayacağı server uygulamalar yazıyorsanız eminim ki hafıza ile ilgili sorunlarla elbet karşılaşacaksınız. Peki bunun bir çaresi yok mu ? Elbette var.. Bunca sıkıcı bilgiden sonra sizi yazının akışına kaptıracak daha somut hususlara değinme zamanı geldi sanırım. Bildiğiniz gibi çalışan bir Windows uygulamasının ekranda görünür halden simge durumuna küçültülmüş(minimize) duruma geçmesi sırasında programın kullandığı hafıza bloğu son derece azalıyor. Peki bu nasıl oluyor da oluyor ? İşletim sistemi tam bu noktada, programınızın Idle konuma alındığını düşünerek onun için hafızada ayırdığı alan üzerinde optimizasyon yapma cihetine gidiyor. Peki ne yapıyor derseniz, hafızada birbirinden kopuk şekilde ayrılmış memory segmentlerini birbirine daha yakın hale getirmeye çalışmak ve page size’dan ötürü fazladan ayrılan ve kullanılmayan hafızayı EnumDesktopProc EnumDesktops Flash Function Pointer GetCurrentProcess GetIconInfo GetKeyState GetLastInputInfo GetProcessMemoryInfo GetStartupInfo GetThreadContext GetTickCount GetTickCount64 Hacking Inheritance InitializeCriticalSection Interface InterlockedCompareExchange InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedIncrement JavaScript LeaveCriticalSection Method Pointer Module32First Module32Next MSSQL OpenDesktop OpenEvent OpenMutex OpenSemaphore OpenWaitableTimer Operator Overloading Persistance Pointer Procedure Pointer Process Process32First Process32Next Query QueryInterface QueryPerformanceCounter Queue ReleaseMutex ReleaseSemaphore Reqursion ResetEvent ResumeThread RTTI SetEvent SetProcessWorkingSetSize SetThreadContext SetWaitableTimer Smilarity SORT SQL SQL Server Stream SuspendThread Sw itchDesktop TDateTime TerminateProcess TerminateThread Thread TInterfacedObject TValue Untyped Parameters VirtualAllocEx VirtualFreeEx WaitForSingleObject WaitForMultipleObjects Weaver WriteProcessMemory _AddRef _Release WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better. Son Yorumlar Yeni Veri Tipleri ve Operator Overloading için Tuğrul HELVACI Yeni Veri Tipleri ve Operator Overloading için Zafer Çelenk Delphi ve Google Maps API için Tuğrul HELVACI Delphi ve Google Maps API için ahmet Ziyaretçi Defteri için Tuğrul HELVACI PDFmyURL.com boşaltmak gibi işlemleri uyguluyor. Ziyaretçi Defteri için Tuğrul HELVACI Peki biz bu işi nasıl yapacağız Uygulamamızı kullanılmadığı zamanlarda minimize mi edeceğiz, kullanılmadığı zamanı nereden bileceğiz, başka yöntemi yokmu ? Uygulamanızı idle olduğu zaman dilimlerinde park etmek yani minimize etmek bir çözüm evet. Ancak bunca karalama yapmamın nedeni elbette bu yöntemi tavsiye etmek değil. Daha şık bir yolu var. Ancak her şık yolda olduğu gibi bu yönteminde kendine has riskli senaryoları var. Windows API Help’te SetProcessWorkingSetSize isimli API tam da bizim istediğimiz işi yapıyor. Bu API kendisine geçilen process için minimum ve maksimum bellek rezarvasyon miktarlarına göre uygulamanın kullandığı hafıza bloğunda genişletme yada daraltmaya gidiyor. SetProcessWorkingSetSize isimli API kernel32.dll içinde bulunmaktadır ve Delphi’de tanımı aşağıdaki şekildedir: 1. 2. Yeni Veri Tipleri ve Operator Overloading Interface Nedir, Nerelerde ve Neden Kullanırız ? Derinlemesine Threading..(3) SQL’de Benzerlik Algoritmaları… Full Text Searching… function SetProcessWorkingSetSize(hProcess: THandle; dwMinimumWorkingSetSize, dwMaximumWorkingSetSize: DWORD): BOOL; stdcall; Minumum ve maximum parametrelerinin DWord olduklarını ve DWord ‘ün işaretsiz 32 bit bir veri tip olduğunu elbette biliyoruz. Bu parametrelere DWord’ün alabileceği maksimum değerler verilerek SetProcessWorkingSetSize API’sinin çağırılması uygulamamızın kullandığı hafıza bloğunun küçültülmesi anlamına gelecektir. Artık yavaş yavaş kod bloklarını vermeye başlayabiliriz. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. Son Yazılar procedure ShrinkMemory; var myProcess : THandle; dwMin, dwMax : DWord; begin dwMin := High(DWord); // Yada $FFFFFFFF dwMax:= High(DWord); // Yada $FFFFFFFF myProcess := GetCurrentProcess; SetProcessWorkingSetSize(myProcess, dwMin, dwMax); end; Yukarıda yazdığımız ShrinkMemory prosedürümüz gerçekten de uygulamamızın kullandığı hafıza bloğunu küçültmektedir. Ancak bu prosedürü kullanırken son derece dikkatli hareket etmemiz gerekir. Çünkü işletim sistemi gerçekte uygulamanın kullandığı hafıza bölgesini sıfırlayıp küçültülmüş hali ile çok kısa bir zaman diliminde yeniden yüklemektedir. İşletim sisteminin bu işlemi yaptığı zaman diliminde sizin uygulamanızın başka herhangi bir işlem yapmıyor olmasının hayati derecede önemi vardır. Yoksa veri kayıplarına ve çeşitli ciddi hatalara açık duruma gelirsiniz. O halde yapmamız gereken tek şey, ilgili ShrinkMemory metodunu uygulamamızın Idle yani kullanılmadığı bir zaman diliminde çağırmak olacaktır. Kategoriler Genel (4) IDE (1) İşletim Sistemi (7) Programlama (43) .Net (3) C# (2) Delphi (43) Grafik (2) Internet (4) Veritabanı (3) Win32 (6) Takvim Temmuz 2010 Pts Sal Çar Per Cum Cts Paz 1 2 3 4 PDFmyURL.com Peki uygulamamızın belli bir müddet kullanılmadığını nereden bilebiliriz ? Bunun bir kaç yolu var. Ben öncelikle size kullanmamanız gereken yöntemi göstereceğim ondan sonra nihai yöntemi aktaracağım. (Sanırım bende her programcı gibi biraz mazoşistim 1. 2. 3. 4. 5. 6. 7. 8. ) function SecondsIdle: DWord; var liInfo: TLastInputInfo; begin liInfo.cbSize := SizeOf(TLastInputInfo) ; GetLastInputInfo(liInfo) ; Result := (GetTickCount - liInfo.dwTime) DIV 1000; end; Bu fonksiyon adından da anlaşılacağı üzere uygulamanın kaç saniye boyunca idle olduğunu anlamanıza yarayacak bir metoddur. Ancak bunu kullanmayacağız. Neden mi ? Çünkü bu fonksiyon işletim sistemindeki giriş aygıtlarının yani klavye mouse gibi ne kadar zamandır kullanılmadığını gösteren işletim sisteminin genelininin bilgisini döndüren bir metoddur. Kısacası sizin uygulamanız kullanılmaz durumda olduğu halde(mesela park halinde) başka uygulamalar üzerinde mouse yada klavye ile birşeyler yapıyorsanız uygulamanızı hâla kullanıyormuşçasına değer döndürecektir bu fonksiyon. Denemesini yapabilirsiniz. O halde biz nihai yöntemimizi sizlerin beğenisine sunalım; 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. var LastTick : DWord = 0; .. .. .. .. //Timer1 : TTimer türünde Interval 1000 //ApplicationEvents1 TApplicationEvents türünde ve OnMessage olay yöneticisinde aşağıdaki kod var. procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean); begin case Msg.message of WM_LBUTTONDOWN , WM_LBUTTONDBLCLK, WM_RBUTTONDOWN , WM_RBUTTONDBLCLK, WM_MOUSEMOVE , WM_KEYDOWN : LastTick := GetTickCount; end; end; 1 5 6 7 8 12 13 14 15 19 20 21 22 26 27 28 29 2 9 16 23 30 3 10 17 24 31 4 11 18 25 « Haz Arşivler Haziran 2010 (1) Mayıs 2010 (1) Nisan 2010 (3) Ağustos 2009 (1) Temmuz 2009 (2) Haziran 2009 (7) Mayıs 2009 (32) Bağlantılar Bir Türkçe Sevdalısı.. Delphi Türkiye Forum Gürcan ÖZTÜRK M.Fatih KÜÇÜKKELEPÇE Memik YANIK Kişisel Memik YANIK’ın Günlüğü Nick Hodges Sinan BARAN Zafer Çelenk procedure TForm1.FormShow(Sender: TObject); begin PDFmyURL.com 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. begin Timer1.Enabled := true; LastTick := GetTickCount; end; procedure TForm1.Timer1Timer(Sender: TObject); var Diff : Extended; begin Diff := (GetTickCount - LastTick) / 1000; if Diff >= 60 then // 60 sn boyunca uygulamam kullanılmaz ise... begin ShrinkMemory; LastTick := GetTickCount; end; end; Yukarıda yazdığımız kod örneği beklendiği şekilde çalışacaktır ancak hâla risklere açık bir hali vardır. Uygulamanız içinde 60 saniyeden daha uzun sürebilecek bir işlem olduğunda(mesela rapor almak amacı ile uzun süren bir sorgunun çalıştırılması vb.) uygulamanıza yönlendirilecek windows mesajları(klavye/mouse vb) uygulamanızın işletim kuyruğuna alınacaklarından henüz işletilmeyecekler ve hafıza küçültme kodumuz devreye girebilecektir. Bu da istenmeyen ciddi sorunlara neden olabilir. Bu durumlar hasıl olacaksa siz siz olun ilgili Timer nesnesini uzun sürecek işlemin başlangıcında durdurun, bitişinde yeniden başlatın. Umarım faydalı olabilmişimdir. Sevgiler, saygılar.. Ziyaretçi Bilgileri Ziyaret: 4 / 12073 Beğenilenler Delphi 2010 (Weaver) ve TValue - 14 votes Derinlemesine Threading..(3) - 13 votes Derinlemesine Threading..(2) - 6 votes Derinlemesine Threading..(1) - 6 votes Yeni Veri Tipleri ve Operator Overloading - 4 votes Win32 & .Net(Delphi->C#) - 4 votes Delphi ve Google Maps API - 3 votes TThread.WaitFor Bug.. - 3 votes BITS(Background Intelligent Transfer Service) ile sessiz sedasız download ;) - 3 votes Bir Kiosk ve CreateDesktop macerası.. - 3 votes [Translate] Meta 2 Comments Veli BOZATLI Yine yararlı, yine bol emek verilmiş, yine değerli bilgiler. Tabiki yine on Haziran 2nd, 2009 Allah razı olsun Programımızın kullandığı hafıza miktarında sürekli artış varsa kesinlikle bir problem olduğu mânâsına mı gelir? Büyük çaplı bir projede böyle birşey farkettim ve FastShareM em + M emCheck ile kontrol ettiğimde onlarca M emory Leak tespit etti. Bunların tek tek düzeltilmesi gerek-şart mıdır? Giriş Yazılar RSS Yorumlar RSS WordPress.org Etiketler-Liste PDFmyURL.com Absolute Tuğrul HELVACI on Haziran 2nd, 2009 Allah sizden de razı olsun. Evet memory leak’lere son derece dikkat etmek gerekir. Bir uygulamanın sürekli surette kullandığı hafıza miktarının artması program içinde memory leak olduğunun göstergesidir. Create ettiğimiz nesnelerin uygun zaman ve yerde Free edilmeleri çok önemlidir. .Net vb platform dillerinde GC adı verilen Garbage Collector ara ara devreye girerek(ne zaman devreye gireceği hakkında net bir malümat yok) kullanılmayan nesneleri temizleme cihetine gider. API Byte Arrays Class Reference COM CreateDesktop CreateProcess CreateRemoteThread CreateToolHelp32SnapShot Function DTS EnumDesktopProc EnumDesktops Pointer GetCurrentProcess GetIconInfo GetKeyState GetLastInputInfo GetProcessMemoryInfo GetStartupInfo Hacking Inheritance Interface JavaScript Method Pointer Module32First Module32Next OpenDesktop Persistance Pointer Procedure Pointer Process Process32First Process32Next RTTI SetProcessWorkingSetSize SQL Server Sw itchDesktop TerminateProcess Reqursion Lâkin bizim Delphi’de böyle prematüre mekanizmalara ihtiyacımız yok. En güzel mekanizmalardan bir tanesi olan Owner mekanizması Delphi’mizde zaten mevcut. Bir nesne Create edilirken içine aldığı parametre genelde anlam yönünden bilinmez. Ama o Owner’dır. Ve owner kendisi yok olmadan evvel sahip olduğu nesneleri kontrol ederek onlara “yok olmaları” gerektiğini söyler. Yada bir diğer mekanizma tasarlayacağınız sınıfların belirli bir interface’i implemente etmeleri olabilir. Bu sınıfın instance’larını interface’lere atarsanız kapsam alanından(scope) çıktıklarında otomatikman temizleneceklerdir. Dikkatli programcı, oluşturduğu nesneyi free edendir Share your comment Name (required) Mail (required) Thread Untyped Parameters VirtualAllocEx WaitForSingleObject VirtualFreeEx WriteProcessMemory Delphi About Auto Select All The Text For TCustomEdit On Mouse Click 29 Haziran 2010 Memory Leak Notification in Delphi - Report Memory Leak on Program Exit 27 Haziran 2010 PCRE Workbench - Regular Expression Test Tool - Source Code Delphi Application 22 Haziran 2010 Deleting Dataset Records In a Loop - Poll Results - Why All Records Are Not Deleted 21 Haziran 2010 Force TListView's Edit Mode using a Keyboard Shortcut 17 Haziran 2010 Implementing On Item Click / Double Click for Delphi's TListView control 16 Haziran 2010 Run Your Delphi Application in Full Screen Implement "F11 - Full Screen" 14 Haziran 2010 PDFmyURL.com Website Displaying Enumerated Properties in a Selectable List - Run-Time Enum Selection in Delphi 10 Haziran 2010 How Do You Delete Dataset Records In a Loop? 08 Haziran 2010 Display Custom Hints for Status Bar Panels 07 Haziran 2010 Sık Ziyaret Edilenler Sayfa: Home (16059) Delphi ve Google Maps API (4132) Delphi ve Google Maps API (1973) Nedir bu Thread’lerden çektiğimiz..! (1444) Delphi & Animated Flash Charts(Fusion Charts) (1174) Delphi & JavaScript Kardeşliği (933) Delphi 2010 (Weaver) ve TValue (918) Derinlemesine Threading..(1) (886) Derinlemesine Threading..(2) (695) Win32 & .Net(Delphi->C#) (617) Kategori: Delphi (613) Bir Kiosk ve CreateDesktop macerası.. (568) Sayfa: Hakkında (563) PDFmyURL.com TThread.WaitFor Bug.. (540) Delphi 2010 (Weaver) ve TValue (530) Oylama.. Sitedeki makaleleri yararlı buluyor musunuz ? Evet, yararlı ama yetersiz. Evet, son derece yararlı. Evet, mükemmel. Hayır, yararlı değil. Hayır, hem yararlı değil, hem de yetersiz. Hayır, rezalet. Vote View Results Delphi'nin hangi sürümünü kullanıyorsunuz ? Delphi 5 yada öncesi Delphi 6 Delphi 7 Delphi 8 Delphi 2005 Delphi 2006 Delphi 2007 PDFmyURL.com Delphi 2009 Delphi 2010 Vote View Results Son Yorumlar Yeni Eklenenler Linkler Yorumunuza teşekkürler. Aslında operatör aşırı yüklemenin sınıflarda pek bir avantaj... by Tuğrul HELVACI Yeni Veri Tipleri ve Operator Overloading Bir Türkçe Sevdalısı.. - Taha EKREM Interface Nedir, Nerelerde ve Neden Kullanırız ? Delphi Türkiye Forum Merhaba, Ben ilk olarak merakımdan dolayı uğraştığım C++ dilinde görmüştüm Operatör... by Zafer Çelenk Derinlemesine Threading..(3) Gürcan ÖZTÜRK - Gürcan ÖZTÜRK SQL’de Benzerlik Algoritmaları… M.Fatih KÜÇÜKKELEPÇE Full Text Searching… Memik YANIK Kişisel Delphi 2010 (Weaver) ve TValue Memik YANIK’ın Günlüğü Derinlemesine Threading..(2) Nick Hodges Merhaba, makaleyi yazdığım zaman kodlarda bir sorun yoktu. Belki Google Maps'de bir şeyler... by Tuğrul HELVACI Merhaba Kodlarda bir sorun mu var? yoksa ggogle bu hizmeti durdurdu mu? Sadece boş bir... by ahmet Programcı arkadaşların daha fazla takıldığı bir yerde yazsa idiniz mesajınızı daha... by Tuğrul HELVACI Sinan BARAN Tuğrul Bey Yeri Burasımıdır Bilmiyorum O nedenle hata ediyorsam özür dilerm bir iş ilanı... by geyikben Teşekkürler ;) by Tuğrul HELVACI Copyright © 2009 Delphi Programming Pow ered by WordPress | Increase Traffic w ith TrafficWhirl. PDFmyURL.com
Benzer belgeler
Yüzen kontroller.. :) | Delphi Programming
BITS(Background Intelligent Transfer Service)
ile sessiz sedasız download ;) - 3 votes
Bir Kiosk ve CreateDesktop macerası.. - 3
votes
Paranoyaklar için :) | Delphi Programming
gostermıyor bu yolla calısan trojanlerde mevcut =) ama gercekten
güzel olmus
- Nicotra Gebhardt
ADH-E fans of the E0, E2, E4, E6 and E7 versions,
from sizes 0160 to 0560,
RDH-E fans of the E0, E2, E4, E6 and E7 versions,
from sizes 0180 to 0560,
ADH and RDH fans of the L, R, K, K1 and K2 vers...