0

我的应用程序只是简单的发送键。我的问题是当我运行我的应用程序时它使用了大约 55-65k 的内存使用量,然后当我将它最小化到系统托盘时,它突然下降到大约 1-3k 的内存使用量,然后当我再次恢复它时,它上升到大约6-8k 内存使用量。我的问题是,即使我没有最小化我的应用程序,我如何才能降低内存使用量?

注意:我尝试等待大约 3 分钟,看看我的应用程序是否会减少它的内存使用量,因为我认为它只是在加载一些组件。但我没有,如果我不最小化它,我会坐在 55-65k 上。

这是我的代码:

Imports System.Runtime.InteropServices
Imports System.Threading
Public Class Form1
    Public Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Integer) As Integer
    Public Declare Sub keybd_event Lib "user32" Alias "keybd_event" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)

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

    Private SearchWindow As String
    Public Const vbKeyQ = 81
    Public Const vbKeyW = 87
    Public Const vbKeyE = 69
    Public Const vbKeyR = 82
    Public Const KEYEVENTF_KEYUP = &H2

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        SearchWindow = "MU"
        Timer1.Enabled = True
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If Control.IsKeyLocked(Keys.CapsLock) Then
            Dim ForeGroundHwnd As IntPtr = GetForegroundWindow
            Dim MySearchWinow As IntPtr = FindWindow(Nothing, SearchWindow)
            If ForeGroundHwnd = MySearchWinow Then
                If rbQ.Checked = True Then
                    keybd_event(vbKeyQ, 0, 0, 0)
                    keybd_event(vbKeyQ, 0, KEYEVENTF_KEYUP, 0)
                ElseIf rbW.Checked = True Then
                    keybd_event(vbKeyW, 0, 0, 0)
                    keybd_event(vbKeyW, 0, KEYEVENTF_KEYUP, 0)
                ElseIf rbE.Checked = True Then
                    keybd_event(vbKeyE, 0, 0, 0)
                    keybd_event(vbKeyE, 0, KEYEVENTF_KEYUP, 0)
                ElseIf rbR.Checked = True Then
                    keybd_event(vbKeyR, 0, 0, 0)
                    keybd_event(vbKeyR, 0, KEYEVENTF_KEYUP, 0)
                End If
            End If
        End If
    End Sub

    Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        Try
            If Me.WindowState = FormWindowState.Minimized Then
                Me.WindowState = FormWindowState.Minimized
                NotifyIcon1.Visible = True
                Me.Hide()
            End If
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

    Private Sub NotifyIcon1_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
        Try
            Me.Show()
            Me.WindowState = FormWindowState.Normal
            NotifyIcon1.Visible = False
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        Me.Close()
    End Sub
End Class
4

2 回答 2

1

当我将它最小化到系统托盘时,它突然下降到大约 1-3k 内存使用量

显然,您正在一个非常旧的操作系统上运行。您根本没有测量内存使用情况,您正在查看程序的工作集。映射到 RAM 的虚拟内存页数。在像 XP 这样的旧操作系统上,内存管理器会在其主窗口最小化时积极修剪进程的工作集。该功能旨在将大量进程压缩到非常小的 RAM 中。XP 只需要 64 兆字节。

它不是免费的,当它再次进入前台时,进程需要时间才能做出响应,那些被映射出来的页面需要重新调入。起初,这只是真正需要的页面你的代码,这就是为什么增加不是那么大。现代版本的 Windows 不再使用此功能,它们现在可以指望具有足够 RAM 的机器。Windows 仅在需要为其他进程腾出空间时才减少程序的工作集。做不需要的工作只是浪费精力。

实际上,您实际上使用的内存比这多得多。虚拟内存。它不需要任何费用,它是虚拟的。妥协你的代码以减少不花费任何成本的东西是没有意义的。而 65KB 的虚拟内存是小菜一碟,只有进程可用内存的 3%。

像 Windows Internals 这样的书是一本很好的书,可以进一步了解 Windows 上的内存管理方式。

于 2013-04-14T03:32:50.280 回答
0

应用程序以这种方式使用内存是正常的。

当您最小化应用程序时,系统会向内存管理器发送一个信号,以尝试释放尽可能多的内存。

通常应用程序不会尝试最小化分配的内存,因为那只是浪费时间。拥有大量可用内存不会使计算机运行得更快,相反,它只会无缘无故地做很多工作。如果您需要内存,内存管理器将尝试释放它。

为了完整起见,我应该提到您可以通过强制垃圾收集来使应用程序使用更少的内存,但这是没有意义的,并且通常被认为是不好的做法。

于 2013-04-14T02:49:03.277 回答