真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

vb.net句柄安全性 vb 句柄

如何在.net應(yīng)用中發(fā)現(xiàn)和避免內(nèi)存和資源泄露

盡管很多人相信在.net應(yīng)用中談及內(nèi)存及資源泄露是件很輕松的事情。但GC(垃圾回收器)并不是魔法師,并不能把你完全從小心翼翼處理內(nèi)存與資源損耗中解放出來(lái)。

為順義等地區(qū)用戶(hù)提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及順義網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站制作、成都做網(wǎng)站、順義網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶(hù)提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶(hù)的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

本文中我將解釋緣何內(nèi)存泄露依然存在以及如何避免其出現(xiàn)。別擔(dān)心,本文不涉及GC內(nèi)部工作機(jī)制及其它.net的資源及內(nèi)存管理等高級(jí)特性中。

理解泄露本身及如何避免其出現(xiàn)很重要,尤其因?yàn)樗鼰o(wú)法輕松地自動(dòng)檢測(cè)到。單元測(cè)試在此方面無(wú)能為力。一旦產(chǎn)品中你的程序崩潰了,你需要馬上找出解決方案。所以在一切都還不是太晚前,花些時(shí)間來(lái)學(xué)習(xí)一下本文吧。

Table of Content

· 介紹

· 泄露?資源?指什么?

· 如何檢測(cè)泄露并找到泄露的資源

· 常見(jiàn)內(nèi)存泄露原因

· 常見(jiàn)內(nèi)存泄露原因演示

· 如何避免泄露

· 相關(guān)工具

· 結(jié)論

· 資源

介紹

近期,我參與了一個(gè)大的.net項(xiàng)目(暫叫它項(xiàng)目X吧),我在項(xiàng)目中負(fù)責(zé)追蹤內(nèi)存與資源泄露。大部分時(shí)間我都花在與GUI關(guān)聯(lián)的泄露上,更準(zhǔn)確地說(shuō)是一個(gè)基于Composite UI Application Block (CAB).的windows窗體應(yīng)用。接下來(lái)我要說(shuō)的直接應(yīng)用到winform上的內(nèi)容,多數(shù)見(jiàn)解同樣可以適用到其它.net應(yīng)用中(像WPF,Silverlight,ASP.NET,Windows service,console application 等等)。

我不是個(gè)處理泄露方面的專(zhuān)家,所以我不得不深入鉆研了一下應(yīng)用程序,做一些清理工作。本文的目標(biāo)是與你們分享在我解決問(wèn)題過(guò)程中的所得所悟。希望能夠幫助那些需要檢測(cè)與解決內(nèi)存、資源泄露問(wèn)題的朋友。下面的概述部分首先會(huì)介紹什么是泄露,之后會(huì)看看如何檢測(cè)到泄露和被泄露資源,以及如何解決與避免類(lèi)似泄露,最后我會(huì)列出一個(gè)對(duì)此過(guò)程有幫助的工具列表及相關(guān)資源。

泄露?資源?指什么?

內(nèi)存泄露

在進(jìn)一步深入前,讓我們先來(lái)定義下我所謂的“內(nèi)存泄露”。簡(jiǎn)單引用在Wikipedia上找到的定義吧。該定義與我打算通過(guò)本文所幫助解決的問(wèn)題完美的一致:

在計(jì)算機(jī)科學(xué)領(lǐng)域中,內(nèi)存泄露是指一種特定的內(nèi)存損耗,該損耗是由一個(gè)計(jì)算機(jī)程序未成功釋放不需要的內(nèi)存引起的。通常是程序中的BUG阻礙了不需要內(nèi)存的釋放。

仍然來(lái)自Wikipedia:”以下語(yǔ)言提供了自動(dòng)的內(nèi)存管理,但并不能避免內(nèi)存泄露。像 Java,C#,VB.NET或是LISP等。”

GC只回收那些不再使用的內(nèi)存。而使用中的內(nèi)存無(wú)法釋放。在.net中,只要有一個(gè)引用指向的對(duì)象均不會(huì)被GC所釋放。

句柄與資源

內(nèi)存可不是唯一被視為資源的。當(dāng)你的.net應(yīng)用程序在Windows上運(yùn)行時(shí),消耗著一個(gè)完整的系統(tǒng)資源集。微軟定義了系統(tǒng)三類(lèi)對(duì)象:用戶(hù)(user),圖形設(shè)備接口(GUI),以及系統(tǒng)內(nèi)核(kernel)。我不會(huì)在此給出完整的分類(lèi)對(duì)象列表,只是指出一些重要的:

· 系統(tǒng)通過(guò)使用用戶(hù)對(duì)象(User objects) 來(lái)支持windows管理。相關(guān)對(duì)象包括:提速緩沖表(Accelerator tables),Carets(補(bǔ)字號(hào)?),指針(Cursors),鉤子(Hooks),圖標(biāo)(Icons),菜單(Menus)和窗體(Windows)。

· GDI對(duì)象 支持圖形繪制:位圖(bitmaps),筆刷(Brushes),設(shè)備上下文(DC),字體(Fonts),內(nèi)存設(shè)置上下文(Memory DCs),元文件(Metafiles),畫(huà)筆(Pens),區(qū)域(Regions)等。

· 內(nèi)核對(duì)象 支持內(nèi)存管理,進(jìn)程執(zhí)行和進(jìn)程間通訊(IPC):文件,進(jìn)程,線(xiàn)程,信號(hào)(Semaphores),定時(shí)器(Timer),訪(fǎng)問(wèn)記號(hào)(Access tokens),套接字(Sockets)等。

所有系統(tǒng)對(duì)象的詳細(xì)情況都可以在MSDN中找到。

系統(tǒng)對(duì)象之外,你還會(huì)碰到句柄(handles).據(jù)MSDN的陳述,應(yīng)用程序不能直接訪(fǎng)問(wèn)對(duì)象數(shù)據(jù)或是對(duì)象所代表的系統(tǒng)資源。取而代之,應(yīng)用程序一定都會(huì)獲得一個(gè)對(duì)象句柄(Handle),可以使用它檢查或是修改系統(tǒng)資源。在.net中無(wú)論如何,多數(shù)情況下系統(tǒng)資源的使用都是透明的,因?yàn)橄到y(tǒng)對(duì)象與句柄都由.net類(lèi)直接或間接代表了。

非托管資源

像系統(tǒng)對(duì)象(System objects)這樣的資源自身都不是個(gè)問(wèn)題,但本文仍涵蓋了它們,因?yàn)橄馱indows這樣的操作系統(tǒng)對(duì)可同時(shí)打開(kāi)的 套接字、文件等的數(shù)量都有限制。所以關(guān)注應(yīng)用程序所使用系統(tǒng)對(duì)象的數(shù)量非常重要。

在特定時(shí)間段內(nèi)一個(gè)進(jìn)程所能使用的User與GDI對(duì)象數(shù)目也是有配額的。缺省值是10000個(gè)GDI對(duì)象和10000個(gè)User對(duì)象。如果想知道本機(jī)的相關(guān)設(shè)置值,可以使用如下的注冊(cè)表鍵:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows: GDIProcessHandleQuota 和 USERProcessHandleQuota.

猜到了什么?確實(shí)沒(méi)有這么簡(jiǎn)單,還有一些你會(huì)很快達(dá)到的其它限制。比如參照:我的一篇有關(guān)桌面堆的博客 所述。

假設(shè)這些值是可以自定義的,你也許認(rèn)為一個(gè)解決方案就是打破默認(rèn)值的限制—調(diào)高這些配額。但我認(rèn)為這可不是個(gè)好主意,有如下原因:

1. 配額存在的原因:系統(tǒng)中不是只有你獨(dú)自一個(gè)應(yīng)用程序,所有運(yùn)行在計(jì)算機(jī)中的其它進(jìn)程與你的應(yīng)用應(yīng)該分享系統(tǒng)資源。

2. 如果你修改配額,使它不同于其它系統(tǒng)了。你不得不確認(rèn)所有你的應(yīng)用程序需要運(yùn)行的機(jī)器都完成了這樣的修改,而且這樣的修改從系統(tǒng)管理員的角度來(lái)說(shuō)是否會(huì)有問(wèn)題也需要確認(rèn)。

3. 大部分都采用了默認(rèn)配額值。如果你發(fā)現(xiàn)配置值對(duì)你應(yīng)用程序來(lái)說(shuō)不夠,那你可能確實(shí)有些清理工作要做了。

如何檢測(cè)泄露及找到泄露的資源

泄露帶來(lái)的實(shí)際問(wèn)題在MSDN上的一篇文章中有著很好的描述:

哪怕在小的泄露只要它反復(fù)出現(xiàn)也會(huì)拖垮系統(tǒng)。

這與水的泄露異曲同工。一滴水的落下不是什么大問(wèn)題。但是一滴一滴如此反復(fù)的泄露也會(huì)變?yōu)橐粋€(gè)大問(wèn)題。

像我稍后解釋的,一個(gè)無(wú)意義的對(duì)象可以在內(nèi)存中維持一整圖的重量級(jí)對(duì)象。

仍然是同一篇文章,你會(huì)了解到:

通常三步根除泄露:

1.發(fā)現(xiàn)泄露

2.找到被泄露的資源

3.決定在源碼中何時(shí)何處釋放該資源

最直接“發(fā)現(xiàn)”泄露的方式是遭受泄露引發(fā)的問(wèn)題

你或許沒(méi)有見(jiàn)過(guò)內(nèi)存不足?!皟?nèi)存不足”提示信息極少出現(xiàn)。因?yàn)椴僮飨到y(tǒng)運(yùn)行中實(shí)際內(nèi)存(RAM)不足時(shí),它會(huì)使用硬盤(pán)空間來(lái)擴(kuò)展內(nèi)存。(稱(chēng)為虛擬內(nèi)存)。

在你的圖形應(yīng)用程序中可能更多出現(xiàn)的是“句柄不足”的異常。準(zhǔn)確的異常不是System.ComponentModel.Win32Exception 就是 System.OutOfMemoryException 均包含如下信息:”創(chuàng)建窗體句柄錯(cuò)誤”。這兩個(gè)異常多發(fā)于兩個(gè)資源被同時(shí)使用的情況下,通常都因?yàn)樵撫尫诺膶?duì)象沒(méi)有被釋放所致。

另外一種你會(huì)經(jīng)常碰到的情況是你的應(yīng)用程序或是整個(gè)系統(tǒng)變更得越來(lái)越慢。這種情況的發(fā)生是因?yàn)槟愕南到y(tǒng)資源即將耗盡。

我來(lái)做個(gè)生硬的推斷:大多數(shù)應(yīng)用程序的泄露在多數(shù)時(shí)間里都不是個(gè)問(wèn)題,因?yàn)橛尚孤秾?dǎo)致出現(xiàn)的問(wèn)題只在你的應(yīng)用程序集中使用很長(zhǎng)時(shí)間的情況下才會(huì)出現(xiàn)。

如果你懷疑有些對(duì)象在應(yīng)該被釋放后仍逗留在內(nèi)存中,那需要做的第一件事就是找出這些對(duì)象都是什么。

這看起來(lái)很明顯,但是找起來(lái)卻不是這樣。

建議通過(guò)內(nèi)存工具找到非預(yù)期逗留在內(nèi)存中的高級(jí)別對(duì)象或是根容器。在項(xiàng)目x中,這些對(duì)象可能是類(lèi)似LayoutView實(shí)例一樣的對(duì)象們(我們使用了MVP(Model View Presentation )模式)。在你的實(shí)際項(xiàng)目中,它可能依賴(lài)于你的根對(duì)象是什么。

下一步就是找出它們?cè)撓s還在的原因。這才是調(diào)試器與工具能真正幫忙的。它們可以顯示出這些對(duì)象是如何鏈接在一起的。通過(guò)查看那些指向“僵尸對(duì)象”(the zombie object)的引用你就可以找到引起問(wèn)題的根本原因了。

你可以選擇 ninja方式(譯者:間諜方式?)(參照 工具介紹章節(jié)中有關(guān) SOS.dll 和 WinDbg 的部分)。

我在項(xiàng)目X中用了JetBrains的dotTrace,本文中我將繼續(xù)使用它來(lái)介紹。在后面的工具相關(guān)章節(jié)中我會(huì)向你更多的介紹該工具。

你的目標(biāo)是找到最終引起問(wèn)題的那個(gè)引用。不要停留在你找到的第一個(gè)目標(biāo)上,但是也要問(wèn)問(wèn)自己為什么這個(gè)家伙還在內(nèi)存中。

常見(jiàn)內(nèi)存泄露的原因

上面提到的泄露情況在.net中較常見(jiàn)。好消息是造成這些泄露的原因并不多。這意味著當(dāng)你嘗試解決一個(gè)泄露問(wèn)題時(shí),不需要在大量可能的原因間搜尋。

我們來(lái)回顧一下這些常見(jiàn)的罪魁禍?zhǔn)?,我把它們區(qū)別開(kāi)來(lái):

· 靜態(tài)引用

· 未注銷(xiāo)的事件綁定

· 未注銷(xiāo)的靜態(tài)事件綁定

· 未調(diào)用Dispose方法

· Dispose方法未正常完成

除了上列典型的原因外,還有些其它情況也可能引發(fā)泄露:

· Windows Forms:綁定源濫用

· CAB:未移除對(duì)工作項(xiàng)的調(diào)用

我只列出了可能在你應(yīng)用程序中出現(xiàn)的一些原因,但應(yīng)該清楚你的應(yīng)用程序依賴(lài)的其它.net代碼、庫(kù)實(shí)際使用中也可能引發(fā)泄露。

我們來(lái)舉個(gè)例子。在項(xiàng)目x中,使用了一套第三方控件來(lái)構(gòu)造界面。其中一個(gè)用來(lái)顯示所有工具欄的控件,它管理著一個(gè)工具欄列表。這種方式?jīng)]什么,但有一點(diǎn),即使被管理的工具欄自身實(shí)現(xiàn)了IDisposable接口,管理類(lèi)卻永遠(yuǎn)也不會(huì)去調(diào)用它的Dispose方法。這是一個(gè)bug.幸運(yùn)的是這發(fā)生在一個(gè)很容易發(fā)現(xiàn)的工作區(qū):只能我們自身來(lái)調(diào)用所有工具樣的Dispose方法了。不幸的是這還不夠,工具欄類(lèi)自身問(wèn)題也不少:它并沒(méi)有釋放自身承載的控件(按鈕,標(biāo)簽等等)。所以在解決方案中還要添加對(duì)每個(gè)工具欄中控件的釋放,但是這次可就沒(méi)那么簡(jiǎn)單了,因?yàn)楣ぞ邫谥械拿總€(gè)子控件都不同。不管怎么樣這只是一個(gè)特殊的例子,我要表達(dá)的觀點(diǎn)是你應(yīng)用程序中使用的任何第三方庫(kù)、組件都可能引發(fā)泄漏。

最后,還有一種由.net framework造成的泄露,由一些不好的使用習(xí)慣引起。即使.net framework自身可能引發(fā)泄露,但這是你極少會(huì)遭遇到的情況。把責(zé)任推到.net身上很容易,但在我們把問(wèn)題推到別人頭上前,還是應(yīng)該先從自身寫(xiě)的代碼出發(fā),看看里面有沒(méi)有問(wèn)題。

常見(jiàn)泄露演示

我已經(jīng)列舉出了泄露主要的來(lái)源,但我還不想僅限于此。如果每個(gè)泄露我都能舉個(gè)鮮活的例子的話(huà),我想本文會(huì)更實(shí)用些。好,我們先啟動(dòng)Vs 和 dotTrace , 然后看些示例代碼。我會(huì)同時(shí)演示如何解決或是避免每個(gè)泄露情況。

項(xiàng)目X中使用了CAB和MVP模式,這意味著界面由工作空間、視圖和呈現(xiàn)者組成。簡(jiǎn)單起見(jiàn),我決定使用包含一組窗口的Winform應(yīng)用。其中使用了與Jossef Goldberg的一篇關(guān)于“Wpf應(yīng)用程序內(nèi)存泄露”文章中相同的方法。甚至我會(huì)直接把相同的例子和事件處理函數(shù)應(yīng)用到我的Winform App中。

我安裝的VB.NET程序,現(xiàn)在調(diào)試時(shí)顯示“綁定句柄無(wú)效”,我重新安裝了一個(gè)還是不行,麻煩各位電腦高手指點(diǎn)

這個(gè)是因?yàn)闆](méi)有事件,或者沒(méi)有函數(shù)的,建議你去檢查一下你的程序,應(yīng)該是你有某個(gè)事件或者函數(shù)沒(méi)聲明的?;蛘吣惆汛a發(fā)出來(lái)

VB.NET和VB6.0有哪些區(qū)別?

VB.net是純面向?qū)ο蟮拈_(kāi)發(fā)語(yǔ)言,為了適應(yīng).net Framework的安全性,vb.net進(jìn)行了不小的調(diào)整。但是關(guān)鍵字修飾符之類(lèi)的基本沒(méi)有什么變化,所以您只需要習(xí)慣.net下的強(qiáng)類(lèi)型,應(yīng)該是不難轉(zhuǎn)型。

舉個(gè)簡(jiǎn)單的例子吧,vb.net下是沒(méi)有“變體類(lèi)型”這一數(shù)據(jù)類(lèi)型的,整型就是整型,字符串就是字符串,像

a = 50 + 60

Text1.Text = a

這樣的代碼是不行的,VB6.0支持變體類(lèi)型,會(huì)自動(dòng)進(jìn)行類(lèi)型轉(zhuǎn)換,而.net下為了保證安全性,會(huì)要求程序員自己進(jìn)行必要的轉(zhuǎn)換。

至于API,.net框架下對(duì)API的依賴(lài)性像VB6中那么高,一些API完成的工作可以由一些類(lèi)庫(kù)來(lái)完成。API的調(diào)用也不是一樣的,因?yàn)橛行〢PI涉及到了“不安全代碼”,而且API是用另一種非.net 語(yǔ)言編寫(xiě)的,所以調(diào)用時(shí)有些特別的要求。

vb.net工作在.NET Framework下,與VB6的解釋執(zhí)行不同,VB.NET是編譯執(zhí)行的,.net下所有的應(yīng)用程序都被編譯成一種“中間語(yǔ)言(MSIL)”的形式,運(yùn)行時(shí)由一種稱(chēng)為即時(shí)編譯器(JIT)的程序進(jìn)行二次編譯。可以說(shuō).net既是開(kāi)發(fā)環(huán)境又是運(yùn)行環(huán)境,它提供了通用類(lèi)型系統(tǒng)(CTS)和“公共語(yǔ)言運(yùn)行時(shí)”(Common Language Runtime,CLR),前者為開(kāi)發(fā)時(shí)提供了類(lèi)型支持,.net下語(yǔ)言中的基本數(shù)據(jù)類(lèi)型都來(lái)自于這個(gè)類(lèi)型系統(tǒng);后者為.net應(yīng)用程序提供了運(yùn)行環(huán)境,包括JIT、GC(內(nèi)存垃圾收集器)等等,同時(shí)負(fù)責(zé)代碼的運(yùn)行時(shí)安全。

最后,我感覺(jué)學(xué)一門(mén)語(yǔ)言并不難,難的是理解一些系統(tǒng)和程序設(shè)計(jì)中低層的東西,不過(guò),我比較建議您學(xué)習(xí)VB.NET,因?yàn)樗募兠嫦驅(qū)ο蟮奶匦员容^符合目前的軟件開(kāi)發(fā)方式。

希望這些信息對(duì)您有幫助。

vb.net WebBrowser 句柄

hwnd = FindWindow(vbNullString, "Form2")

hwnd = FindWindowEx(hwnd, 0, "WindowsForms10.Window.8.app.0.378734a", vbNullString)

加一句 至于WindowsForms10.Window.8.app.0.378734a 這個(gè)類(lèi)名是vs 08版的 至于其他版本自行用spy++查看

在vb.net中什么是窗口句柄 高手用通俗語(yǔ)言解釋

句柄是 Windows 系統(tǒng)中的概念,和VB.NET無(wú)關(guān)。

通俗地講,句柄就是一個(gè)數(shù)字,也就是一個(gè)編號(hào)。

比如說(shuō),你電腦中有10個(gè)窗口,每個(gè)窗口都會(huì)有一個(gè)編號(hào),這是操作系統(tǒng)區(qū)分各個(gè)窗口的依據(jù)

vb.net 創(chuàng)建窗口句柄時(shí)出錯(cuò),Timer 中出現(xiàn)問(wèn)題

因?yàn)槟愦翱陉P(guān)閉的時(shí)候Time并沒(méi)有釋放,但是此時(shí)Label已經(jīng)不能訪(fǎng)問(wèn)了

才會(huì)出現(xiàn)窗口句柄出錯(cuò),你試試加上下面的話(huà)

Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing

timer1.Close()

timer2.Close()

End Sub

應(yīng)該就不會(huì)報(bào)錯(cuò)了。

希望能幫到你。


新聞標(biāo)題:vb.net句柄安全性 vb 句柄
本文鏈接:http://weahome.cn/article/dooidhi.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部