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

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

cabvb.net的簡(jiǎn)單介紹

vb打包問題

你好象一共提了3問題,分別簡(jiǎn)單回答一下:

成都創(chuàng)新互聯(lián)公司是一家朝氣蓬勃的網(wǎng)站建設(shè)公司。公司專注于為企業(yè)提供信息化建設(shè)解決方案。從事網(wǎng)站開發(fā),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),網(wǎng)站模板,微信公眾號(hào)開發(fā),軟件開發(fā),微信小程序開發(fā),十余年建站對(duì)成都白烏魚等多個(gè)方面,擁有豐富的網(wǎng)站維護(hù)經(jīng)驗(yàn)。

1、你給別人的安裝文件應(yīng)該包括:setup.exe、CAB文件和lst文件。

2、lst文件是VB6安裝制作程序生成的一個(gè)安裝信息文件,用記事本可以打開。

3、用VB6安裝制作程序制作安裝包,需要把你程序中用到一些東西也打包進(jìn)來才能完整安裝,比如用VB6做打印程序就需要添加MSDBRPTR.DLL。另外,想要做成只有一個(gè)setup.exe程序需要借助第三方工具了。

vb小游戲代碼 急求。。。。。

Option Explicit

'五子棋程序 人機(jī)對(duì)戰(zhàn)版本

'需要2個(gè)Label控件 2個(gè)CommandButton控件

Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

Private Declare Function CreateRoundRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long) As Long

'Dim PlayStep() As String '記錄棋譜的數(shù)組

'Dim Label2Cap As String

Private Const BoxL As Single = 50, BoxT As Single = 50, BoxW As Single = 25, BoxN As Integer = 18

Dim Table() As Long '棋盤(0-BoxN,0-BoxN) 0-空 1-黑子 2-白子

Dim PsCore() As Long '定義當(dāng)前玩家桌面空格的分?jǐn)?shù)

Dim CsCore() As Long '定義當(dāng)前電腦桌面空格的分?jǐn)?shù)

Dim pWin() As Boolean '定義玩家的獲勝組合

Dim cWin() As Boolean '定義電腦的獲勝組合

Dim pFlag() As Boolean '定義玩家的獲勝組合標(biāo)志

Dim cFlag() As Boolean '定義電腦的獲勝組合標(biāo)志

Dim ThePlayFlag As Boolean '定義游戲有效標(biāo)志

Private Sub Command1_Click()

If Not ThePlayFlag Then Call InitPlayEnvironment: Exit Sub

If MsgBox("本局還沒有下完,是否重新開始?(Y/N)", vbYesNo) = vbNo Then Exit Sub

Call InitPlayEnvironment

End Sub

Private Sub Command2_Click()

End

End Sub

Private Sub Form_Load()

MsgBox "五子棋之人機(jī)對(duì)戰(zhàn)系統(tǒng),作者:楊海", vbOKOnly, "楊海作品"

Dim i As Long, lw As Long, lh As Long

'Label2Cap = "000 黑方 行 00 列 00"

Me.Width = 10815: Me.Height = 8200: Me.Caption = "五子棋 - 人機(jī)對(duì)戰(zhàn) 作者:盧霞": Me.Show

lw = Me.Width \ Screen.TwipsPerPixelX: lh = Me.Height \ Screen.TwipsPerPixelY

SetWindowRgn Me.hWnd, CreateRoundRectRgn(0, 0, lw, lh, 10, 10), True

With Label1

.Alignment = vbCenter: .FontSize = 12: .FontBold = True

.ForeColor = vbRed: .BackStyle = 0: .AutoSize = True: .Move 8910, 510

End With

Label2.AutoSize = True: Label2.WordWrap = True

Label2.BackStyle = 0: Label2.Move 8040, 1050, 2280

Command1.Move 8025, 7035, 1020, 435: Command1.Caption = "再來一局"

Command2.Move 9300, 7035, 1020, 435: Command2.Caption = "不玩了"

Call DrawChessBoard: Me.FillStyle = 0: Call InitPlayEnvironment

End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)

End

End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

Dim iRow As Long, iCol As Long, i As Long, k As Long, t As String

If Not ThePlayFlag Then Exit Sub

If Button = vbLeftButton Then '左鍵下棋

iRow = -1: iCol = -1

For i = 0 To BoxN '鼠標(biāo)必須落在交叉點(diǎn) 半徑10以內(nèi) 若是則給出行列號(hào)

If (Y + 10) (BoxT + i * BoxW) And (Y - 10) = (BoxT + i * BoxW) Then iRow = i

If (X + 10) (BoxL + i * BoxW) And (X - 10) = (BoxL + i * BoxW) Then iCol = i

Next

If (iRow = -1) Or (iCol = -1) Then Beep: Exit Sub

If Table(iCol, iRow) 0 Then Exit Sub

Table(iCol, iRow) = 2: Label1.Caption = "下一步 黑方"

Me.FillColor = vbWhite: Me.Circle (iCol * BoxW + BoxT, iRow * BoxW + BoxL), 8

For i = 0 To UBound(cWin, 3)

If cWin(iCol, iRow, i) = True Then cFlag(i) = False

Next

Call CheckWin: Call DianNao '檢查當(dāng)前玩家是否獲勝 調(diào)用電腦算法

End If

End Sub

Public Sub InitPlayEnvironment()

'*****************************************************************************

' 模塊名稱: InitPlayEnvironment [初始化過程]

'

' 描述: 1. 設(shè)置背景音樂。 2. 設(shè)置游戲狀態(tài)有效。

' 3. 初始化游戲狀態(tài)標(biāo)簽。 4. 直接指定電腦的第一步走法。

' 5. 初始化基本得分桌面。 6. 電腦和玩家獲勝標(biāo)志初始化。

' 7. 初始化所有獲勝組合。 8. 重新設(shè)定玩家的獲勝標(biāo)志。

'*****************************************************************************

Dim i As Long, j As Long, m As Long, n As Long

ThePlayFlag = True: Label1.Caption = "下一步 白方": Label2.Caption = ""

Me.FillColor = vbBlack: Me.FillStyle = 0: Me.AutoRedraw = True

Me.Cls: Me.Circle (9 * BoxW + BoxL, 9 * BoxW + BoxT), 8

ReDim Table(0 To BoxN, 0 To BoxN) As Long

ReDim pFlag(NumsWin(BoxN + 1) - 1) As Boolean

ReDim cFlag(UBound(pFlag)) As Boolean

ReDim PsCore(BoxN, BoxN) As Long, CsCore(BoxN, BoxN) As Long

ReDim pWin(BoxN, BoxN, UBound(pFlag)) As Boolean

ReDim cWin(BoxN, BoxN, UBound(pFlag)) As Boolean

For i = 0 To UBound(pFlag): pFlag(i) = True: cFlag(i) = True: Next

Table(9, 9) = 1 '假定電腦先手 并下了(9, 9)位 將其值設(shè)為1

'******** 初始化獲勝組合 ****************************************

For i = 0 To BoxN: For j = 0 To BoxN - 4

For m = 0 To 4

pWin(j + m, i, n) = True: cWin(j + m, i, n) = True

Next

n = n + 1

Next: Next

For i = 0 To BoxN: For j = 0 To BoxN - 4

For m = 0 To 4

pWin(i, j + m, n) = True: cWin(i, j + m, n) = True

Next

n = n + 1

Next: Next

For i = 0 To BoxN - 4: For j = 0 To BoxN - 4

For m = 0 To 4

pWin(j + m, i + m, n) = True: cWin(j + m, i + m, n) = True

Next

n = n + 1

Next: Next

For i = 0 To BoxN - 4: For j = BoxN To 4 Step -1

For m = 0 To 4

pWin(j - m, i + m, n) = True: cWin(j - m, i + m, n) = True

Next

n = n + 1

Next: Next

'******** 初始化獲勝組合結(jié)束 *************************************

For i = 0 To UBound(pWin, 3) '由于電腦已下了(9, 9)位 所以需要重新設(shè)定玩家的獲勝標(biāo)志

If pWin(9, 9, i) = True Then pFlag(i) = False

Next

End Sub

Public Function DrawChessBoard() As Long

'容器的(BoxL, BoxT)為左上角坐標(biāo)畫一個(gè) BoxN*BoxN, 每格邊長(zhǎng)為 BoxW 象素的棋盤

Dim i As Long, j As Long, cx As Long, cy As Long

Me.ScaleMode = 3: Me.FillStyle = 1: Me.AutoRedraw = True: Me.Cls

For i = 0 To BoxN '畫棋盤

Me.Line (BoxL + i * BoxW, BoxT)-(BoxL + i * BoxW, BoxT + BoxN * BoxW)

Me.Line (BoxL, BoxT + i * BoxW)-(BoxL + BoxN * BoxW, BoxT + i * BoxW)

Me.CurrentX = BoxL + i * BoxW - IIf(i 9, 6, 2)

Me.CurrentY = BoxT - 20: Me.Print Format(i)

Me.CurrentX = BoxL - IIf(i 9, 23, 20)

Me.CurrentY = BoxT + i * BoxW - 6: Me.Print Format(i)

Next

For i = 3 To 16 Step 6: For j = 3 To 16 Step 6 '畫小標(biāo)志

cx = BoxL + j * BoxW - 3: cy = BoxT + i * BoxW - 3

Me.Line (cx, cy)-(cx + 6, cy + 6), , B

Next: Next

Me.AutoRedraw = False: Set Me.Picture = Me.Image

End Function

Public Sub CheckWin()

'*****************************************************************************

' 模塊名稱: CheckWin [獲勝檢查算法]

'

' 描述: 1. 檢查是否和棋。 2. 檢查電腦是否獲勝。 3. 檢查玩家是否獲勝。

'*****************************************************************************

Dim i As Long, j As Long, k As Long, m As Long, n As Long

Dim cA As Long, pA As Long, cN As Long

For i = 0 To UBound(cFlag): cN = IIf(cFlag(i) = False, cN + 1, cN): Next

If cN = UBound(cFlag) - 1 Then '設(shè)定和棋規(guī)則

Label1.Caption = "雙方和棋!": ThePlayFlag = False: Exit Sub

End If

For i = 0 To UBound(cFlag) '檢查電腦是否獲勝

If cFlag(i) = True Then

cA = 0: For j = 0 To BoxN: For k = 0 To BoxN

If Table(j, k) = 1 And cWin(j, k, i) = True Then cA = cA + 1

Next: Next

If cA = 5 Then Label1.Caption = "電腦獲勝!": ThePlayFlag = False: Exit Sub

End If

Next

For i = 0 To UBound(pFlag) '檢查玩家是否獲勝

If pFlag(i) = True Then

pA = 0: For j = 0 To BoxN: For k = 0 To BoxN

If Table(j, k) = 2 And pWin(j, k, i) = True Then pA = pA + 1

Next: Next

If pA = 5 Then Label1.Caption = "玩家獲勝!": ThePlayFlag = False: Exit Sub

End If

Next

End Sub

Public Sub DianNao()

'*****************************************************************************

' 模塊名稱: DianNao [電腦算法]

' 描述: 1. 初始化賦值系統(tǒng)。 2. 賦值加強(qiáng)算法。 3. 計(jì)算電腦和玩家的最佳攻擊位。

' 4. 比較電腦和玩家的最佳攻擊位并決定電腦的最佳策略。 5. 執(zhí)行檢查獲勝函數(shù)。

'*****************************************************************************

Dim i As Long, j As Long, k As Long, m As Long, n As Long

Dim Dc As Long, cAb As Long, pAb As Long

ReDim PsCore(BoxN, BoxN) As Long, CsCore(BoxN, BoxN) As Long '初始化賦值數(shù)組

'******** 電腦加強(qiáng)算法 ********

For i = 0 To UBound(cFlag)

If cFlag(i) = True Then

cAb = 0

For j = 0 To BoxN: For k = 0 To BoxN

If Table(j, k) = 1 And cWin(j, k, i) = True Then cAb = cAb + 1

Next: Next

Select Case cAb

Case 3

For m = 0 To BoxN: For n = 0 To BoxN

If Table(m, n) = 0 And cWin(m, n, i) = True Then CsCore(m, n) = CsCore(m, n) + 5

Next: Next

Case 4

For m = 0 To BoxN: For n = 0 To BoxN

If Table(m, n) = 0 And cWin(m, n, i) = True Then

Table(m, n) = 1: Label1.Caption = "下一步 白方"

Me.FillColor = vbBlack: Me.Circle (m * BoxW + BoxL, n * BoxW + BoxT), 8

For Dc = 0 To UBound(pWin, 3)

If pWin(m, n, Dc) = True Then pFlag(Dc) = False: Call CheckWin: Exit Sub

Next

End If

Next: Next

End Select

End If

Next

For i = 0 To UBound(pFlag)

If pFlag(i) = True Then

pAb = 0

For j = 0 To BoxN: For k = 0 To BoxN

If Table(j, k) = 2 And pWin(j, k, i) = True Then pAb = pAb + 1

Next: Next

Select Case pAb

Case 3

For m = 0 To BoxN: For n = 0 To BoxN

If Table(m, n) = 0 And pWin(m, n, i) = True Then PsCore(m, n) = PsCore(m, n) + 30

Next: Next

Case 4

For m = 0 To BoxN: For n = 0 To BoxN

If Table(m, n) = 0 And pWin(m, n, i) = True Then

Table(m, n) = 1: Label1.Caption = "下一步 白方"

Me.FillColor = vbBlack: Me.Circle (m * BoxW + BoxL, n * BoxW + BoxT), 8

For Dc = 0 To UBound(pWin, 3)

If pWin(m, n, Dc) = True Then pFlag(Dc) = False: Call CheckWin: Exit Sub

Next

End If

Next: Next

End Select

End If

Next

'******** 電腦加強(qiáng)算法結(jié)束 ********

'******** 賦值系統(tǒng) ****************

For i = 0 To UBound(cFlag)

If cFlag(i) = True Then

For j = 0 To BoxN: For k = 0 To BoxN

If (Table(j, k) = 0) And cWin(j, k, i) Then

For m = 0 To BoxN: For n = 0 To BoxN

If (Table(m, n) = 1) And cWin(m, n, i) Then CsCore(j, k) = CsCore(j, k) + 1

Next: Next

End If

Next: Next

End If

Next

For i = 0 To UBound(pFlag)

If pFlag(i) = True Then

For j = 0 To BoxN: For k = 0 To BoxN

If (Table(j, k) = 0) And pWin(j, k, i) Then

For m = 0 To BoxN: For n = 0 To BoxN

If (Table(m, n) = 2) And pWin(m, n, i) Then PsCore(j, k) = PsCore(j, k) + 1

Next: Next

End If

Next: Next

End If

Next

'******** 賦值系統(tǒng)結(jié)束 ************

'******** 分值比較算法 ************

Dim a As Long, b As Long, c As Long, d As Long

Dim cS As Long, pS As Long

For i = 0 To BoxN: For j = 0 To BoxN

If CsCore(i, j) cS Then cS = CsCore(i, j): a = i: b = j

Next: Next

For i = 0 To BoxN: For j = 0 To BoxN

If PsCore(i, j) pS Then pS = PsCore(i, j): c = i: d = j

Next: Next

If cS pS Then

Table(a, b) = 1: Label1.Caption = "下一步 白方"

Me.FillColor = vbBlack: Me.Circle (a * BoxW + BoxL, b * BoxW + BoxT), 8

For i = 0 To UBound(pWin, 3)

If pWin(a, b, i) = True Then pFlag(i) = False

Next

Else

Table(c, d) = 1: Label1.Caption = "下一步 白方"

Me.FillColor = vbBlack: Me.Circle (c * BoxW + BoxL, d * BoxW + BoxL), 8

For i = 0 To UBound(pWin, 3)

If pWin(c, d, i) = True Then pFlag(i) = False

Next

End If

'******** 分值比較算法結(jié)束 ********

Call CheckWin

End Sub

Public Function NumsWin(ByVal n As Long) As Long

'根據(jù)輸入的棋盤布局 n*n 計(jì)算總共有多少種獲勝組合

'假定棋盤為 10 * 10 相應(yīng)的棋盤數(shù)組就是 Table(9, 9)

'水平方向 每一列獲勝組合是6 共10列 6*10=60

'垂直方向 每一行獲勝組合是6 共10行 8*10=60

'正對(duì)角線方向 6 + (5 + 4 + 3 + 2 + 1) * 2 = 36

'反對(duì)角線方向 6 + (5 + 4 + 3 + 2 + 1) * 2 = 36

'總的獲勝組合數(shù)為 60 + 60 + 36 + 36 = 192

Dim i As Long, t As Long

For i = n - 5 To 1 Step -1: t = t + i: Next

NumsWin = 2 * (2 * t + n - 4) + 2 * n * (n - 4)

End Function

vb.net把dll放到程序的Resources資源里面,能直接調(diào)用Resources里面的dll嗎?

dll文件可以直接引用進(jìn)去啊,你打開引用文件,直接引用進(jìn)去就好了,是在程序引用里面,本身就融合在exe文件里,何必放在Resource目錄下,畫蛇添足。

一些特定的文件,如DB格式、Cab格式、圖片格式直接放在相對(duì)目錄下不就好了,不然你要開發(fā)一個(gè)稍微像樣點(diǎn)的軟件根本沒辦法打包給別人,資源包和檢測(cè)安裝包你怎么給別人打包安裝嘛?Resource目錄是針對(duì)ASP.NET WebForm程序,MapPath的方法可以直接取得資源目錄。WinForm考慮他的項(xiàng)目移植性,你直接做安裝包就好了,安裝資源文件到哪個(gè)位置應(yīng)該由客戶自己來定。

dll本身就是封裝好的代碼,可以直接引用編譯,不屬于資源文件行列。

第三方控件也不是什么恥辱的事情,大部分成功的軟件都是自己開發(fā)第三方控件,你用微軟自帶的控件根本滿足不了市場(chǎng)需求,僅僅維持一個(gè)學(xué)習(xí)層次。

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

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

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

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

Table of Content

· 介紹

· 泄露?資源?指什么?

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

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

· 常見內(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)確地說是一個(gè)基于Composite UI Application Block (CAB).的windows窗體應(yīng)用。接下來我要說的直接應(yīng)用到winform上的內(nèi)容,多數(shù)見解同樣可以適用到其它.net應(yīng)用中(像WPF,Silverlight,ASP.NET,Windows service,console application 等等)。

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

泄露?資源?指什么?

內(nèi)存泄露

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

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

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

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

句柄與資源

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

· 系統(tǒng)通過使用用戶對(duì)象(User objects) 來支持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),畫筆(Pens),區(qū)域(Regions)等。

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

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

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

非托管資源

像系統(tǒng)對(duì)象(System objects)這樣的資源自身都不是個(gè)問題,但本文仍涵蓋了它們,因?yàn)橄馱indows這樣的操作系統(tǒng)對(duì)可同時(shí)打開的 套接字、文件等的數(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í)沒有這么簡(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)管理員的角度來說是否會(huì)有問題也需要確認(rèn)。

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

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

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

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

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

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

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

通常三步根除泄露:

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

2.找到被泄露的資源

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

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

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

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

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

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

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

這看起來很明顯,但是找起來卻不是這樣。

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

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

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

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

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

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

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

我們來回顧一下這些常見的罪魁禍?zhǔn)祝野阉鼈儏^(qū)別開來:

· 靜態(tài)引用

· 未注銷的事件綁定

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

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

· Dispose方法未正常完成

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

· Windows Forms:綁定源濫用

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

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

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

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

常見泄露演示

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

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


分享題目:cabvb.net的簡(jiǎn)單介紹
網(wǎng)站路徑:http://weahome.cn/article/dojijsh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部