vb 有内存溢出

zenmirco 2013-04-15 02:25:09
只要是执行下面这段代码 内存就会不停的增加,我应该怎么调整下才能够不让内存溢出呢?


Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long

Private Sub Form_Load()
Me.BorderStyle = 0
Me.Caption = ""
Me.WindowState = 2
End Sub

Private Sub Timer1_Timer()
If FindWindow("TFormLogin", vbNullString) <> 0 Then
Timer2.Enabled = True
Timer1.Enabled = False
End If
End Sub

Private Sub Timer2_Timer()
If FindProcess("BJMain.exe") = 0 Then
Timer2.Enabled = False
Unload Form6
End If
End Sub
Private Sub form6_unload()
Timer1.Enabled = False
Timer2.Enabled = False
Set Form6 = Nothing
End Sub
...全文
267 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
东方之珠 2013-04-15
  • 打赏
  • 举报
回复
进程可以一次枚举完毕,如果要用定时器的话,可以在Command1中进程刷新,在DO循环中查找,Command2不再需要了。
zenmirco 2013-04-15
  • 打赏
  • 举报
回复
看起来不是很明白。为什么不用定时器,如果不用定时器的话,怎么能一直监控窗体和进程存不存在呢??
东方之珠 2013-04-15
  • 打赏
  • 举报
回复
通过枚举进程可以找到指定进程: 标准模块:
Option Explicit
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Declare Function NtQuerySystemInformation Lib "NTDLL.DLL" (ByVal dwInfoType As Long, lpStructure As Any, ByVal dwSize As Long, dwReserved As Long) As Long

Public Type LARGE_INTEGER
    LowPart As Long
    HighPart As Long
End Type
Public Type IO_COUNTERS
    ReadOperationCount As LARGE_INTEGER
    WriteOperationCount As LARGE_INTEGER
    OtherOperationCount As LARGE_INTEGER
    ReadTransferCount As LARGE_INTEGER
    WriteTransferCount As LARGE_INTEGER
    OtherTransferCount As LARGE_INTEGER
End Type
Public Type VM_COUNTERS
    PeakVirtualSize As Long
    VirtualSize As Long
    PageFaultCount As Long
    PeakWorkingSetSize As Long
    WorkingSetSize As Long
    QuotaPeakPagedPoolUsage As Long
    QuotaPagedPoolUsage As Long
    QuotaPeakNonPagedPoolUsage As Long
    QuotaNonPagedPoolUsage As Long
    PagefileUsage As Long
    PeakPagefileUsage As Long
End Type
Public Type CLIENT_ID
    UniqueProcess As Long
    UniqueThread As Long
End Type

Public Type SYSTEM_THREAD_INFORMATION
    KernelTime As LARGE_INTEGER
    UserTime As LARGE_INTEGER
    CreateTime As LARGE_INTEGER
    WaitTime As Long
    StartAddress As Long 'pointer
    ClientId As CLIENT_ID
    Priority As Long
    BasePriority As Long
    ContextSwitchCount As Long
    State As Long 'THREAD_STATE
    WaitReason As Long 'KWAIT_REASON
End Type


Public Type UNICODE_STRING
    Length As Integer
    MaximumLength As Integer
    buffer As Long
End Type

Public Type SYSTEM_PROCESS_INFORMATION
    NextEntryDelta As Long
    ThreadCount As Long
    Reserved1(5) As Long
    CreateTime As LARGE_INTEGER
    UserTime As LARGE_INTEGER
    KernelTime As LARGE_INTEGER
    ProcessName As UNICODE_STRING
    BasePriority As Long
    ProcessID As Long
    InheritedFromProcessId As Long
    HandleCount As Long
    Reserved2(1) As Long
    VmCounters As VM_COUNTERS
    IoCounters As IO_COUNTERS
    Threads(0) As SYSTEM_THREAD_INFORMATION
End Type

Public Const SystemProcessesAndThreadsInformation = 5

Public Function Li2Double(X As LARGE_INTEGER) As Double
        Li2Double = CDbl(X.HighPart) * 4294967296# + CDbl(X.LowPart)
End Function
Form1窗体模块:
Option Explicit

Private Sub Command1_Click()
    Dim Process As SYSTEM_PROCESS_INFORMATION '进程结构
    Dim buf() As Byte '接受信息BYTE
    Dim buffer As Long '缓冲区长度
    Dim NextProcess As Long '下个进程偏移量
    Dim ProcessName As String '进程名
    
    buffer = LenB(Process)
    ReDim buf(buffer)
    
    Do While NtQuerySystemInformation(SystemProcessesAndThreadsInformation, buf(0), buffer, 0)
        buffer = buffer * 2
        ReDim buf(buffer)
    Loop
    '执行成功后
    CopyMemory Process, buf(0), LenB(Process) '复制BYTE数据到进程结构
    
    Do While Process.NextEntryDelta <> 0 '如果存在下个链表
        NextProcess = Process.NextEntryDelta + NextProcess '下个进程地址
        CopyMemory Process, buf(NextProcess), LenB(Process) '复制BYTE数据到进程结构
        
        ProcessName = Space(Process.ProcessName.Length / 2) '缓冲区
        CopyMemory ByVal StrPtr(ProcessName), ByVal Process.ProcessName.buffer, Process.ProcessName.Length '还原字符串
        List1.AddItem Process.ProcessID & vbTab & ProcessName & vbTab & Li2Double(Process.UserTime)
    Loop
End Sub

Private Sub Command2_Click()
    Dim i As Long
    For i = 0 To List1.ListCount - 1
        If InStr(1, List1.List(i), "BJMain.exe") > 0 Then
           Set Form6 = Nothing: Exit For
        End If
    Next
End Sub
zenmirco 2013-04-15
  • 打赏
  • 举报
回复
引用 1 楼 chenjl1031 的回复:
Visual Basic code?123456789101112131415161718192021222324Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) A……
你这样把定时器改成command 我怎么能让系统自动判断窗体及进程存不存在呢?
东方之珠 2013-04-15
  • 打赏
  • 举报
回复
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long

Private Sub Form_Load()
 Me.BorderStyle = 0
 Me.Caption = ""
 Me.WindowState = 2
End Sub

Private Sub Command1_Click()
    If FindWindow("TFormLogin", vbNullString) <> 0 Then
       call Command2_Click
    End If
End Sub

Private Sub Command2_Click()
    If FindProcess("BJMain.exe") = 0 Then
       call form6_unload
    End If
End Sub
Private Sub form6_unload()
    Set Form6 = Nothing
End Sub
比网上其他版本(也包括之前在此发的两次)修正: 去除tab只有9页的限制 修正tab页宽度超过1万后,应该在其他页中的控件会留一部分在当前页 放多个没有left、top或WhatsThisHelpID的控件不会产生错误(只是不会随页变动) 修正tabstop不能保持原值错误 修正鼠标停在tab上会不断刷新占用系统资源甚至内存溢出错误(去除usercontrol_mouseover中refresh) tab标题头背景透明处理(美化了^_^) '-------------------------------------------- 修正后仍存在的不足 -------------------------------- 1、控件必须编译后使用,否则一旦拖放出新的adodc等会让自定义控件变为不可用状态的控件,TAB则会跳页错乱! 2、tab控件中的WhatsThisHelpID属性被占用(-_-#,没办法,为了省系统资源,好在多数控件有这个属性且基本没人用,偷笑^^) 3、没有WhatsThisHelpID属性的控件不会随页变动 4、如果把本控件的BackColor设成&H00FF00DA& ,则所有放在Tab页上的控件将与背景一起被透明掉。 (本控件会重画放在其上的控件,所以控件也会被透明) 这个问题其实不算问题,没人必须把背景色设的和这个完全一样吧^^,哪怕差1也可以啊,点明这个问题只是要说明本控件的背景透明或任意形状控件的制作原理 原理: backstyle设为:0 maskColor设为:&H00FF00DA& (这个控件里UserControl的BackColor也要设为:&H00FF00DA&) 在Refresh方法中将在UserControl中重绘好的图作为maskPicture,即: Set UserControl.MaskPicture = UserControl.Image 这样maskpicture中背景没有被重绘的部分保持&H00FF00DA&(即与maskcolor指定的颜色相同色),该颜色的部分即被透明 (注意,指定了backstyle=0及maskpicture后超出maskpicture大小的部分全部会被透明)!!! '---------------------------------------------------------比这个前一个版本的是没有用API的,可以在我的资源里找到前两次修改的版本,使用的话还是用这个版本 这几个控件有很多可学的地方, 比如其中的错误处理(网上的源码和我上一个修改版本的源码中错误处理的部分是不太合理的,虽然我和这个控件的其他修改者一样思路,但研究后最终还是用这次发布的这个版本) 比如上一版本中的无API绘图,这个版本有api,因此图大小可变 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 测试.vbp那个是原先旧版的测试,没有跟着新版修改,所以不兼容,此楼新版是经过测试的,编译好的ocx可以直接使用(★必须使用编译好的ocx,原因一楼已经说了★) 对编译好的ocx有疑问或自己要改进的可以直接修改TabSwitch.vbp,再重新编译

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧