【问题标题】:Memory Leak When using InkEdit control使用 InkEdit 控件时的内存泄漏
【发布时间】:2021-12-06 19:54:37
【问题描述】:

我们有一个使用 Microsoft InkEdit 控件的 Windows 窗体应用程序。 15 年来,这一直不是问题。在 Windows 7、8 和 10 上运行良好。但是,最近的 Windows 10 更新在调用此控件时引入了内存泄漏。

Stack Overflow 上有一个类似的问题: [https://stackoverflow.com/questions/63645140/memory-leaks-in-inkedit-control]

我们已经在我们的代码中实现了这些解决方案,但是我们仍然存在内存泄漏。

分析似乎表明 windows DLL mshwLatin.dll 正在泄漏内存。

我正在展示一个简单的示例来复制问题。同样,发生在最新的 Windows 10 上。让一个窗口调用此窗口,然后将其关闭。我的示例应用从 4MB 开始,在打开和关闭 7-10 次后增长到 100MB 以上。

寻找内存泄漏的解决方案(如果有)或如何最好地向 Microsoft 报告此问题。

Imports Microsoft.Ink  

Public Class Form2  
    Dim inkfield As New InkEdit  
    Dim inkfield2 As New InkEdit  
    Dim inkfield3 As New InkEdit  
    Dim inkfield4 As New InkEdit  
    Dim inkfield5 As New InkEdit  

    Public Sub New()  

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.Controls.Add(inkfield)
        Me.Controls.Add(inkfield2)
        Me.Controls.Add(inkfield3)
        Me.Controls.Add(inkfield4)
        Me.Controls.Add(inkfield5)
        inkfield.Location = New Point(10, 10)
        inkfield2.Location = New Point(10, 40)
        inkfield3.Location = New Point(10, 70)
        inkfield4.Location = New Point(10, 100)
        inkfield5.Location = New Point(10, 150)
        inkfield.Height = 24
        inkfield2.Height = 24
        inkfield3.Height = 24
        inkfield4.Height = 24
        inkfield5.Height = 24
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Me.Close()
    End Sub

End Class

【问题讨论】:

  • 这不再被支持所以真的不应该在新代码中使用。至于文档中的问题,警告“为避免内存泄漏,您必须在对象超出范围之前显式调用已附加事件处理程序的任何 InkEdit 对象上的 Dispose 方法。”
  • @Mary 非常正确,一般来说,Roger 任何实现 IDisposable 的东西都应该在完成后处理掉。 Public Class Ink Implements ICloneable, IDisposable
  • 感谢 cmets。在我的实际代码中,我们确实在关闭窗口之前处理了对象。这仍然会留下内存泄漏。在提供的示例中也这样做了,但仍然会导致内存泄漏。 MARY:您能否指出不再支持此功能的地方以及将使用什么来代替它。谢谢。

标签: vb.net winforms memory-leaks


【解决方案1】:

我不知道这是否适合你,但你可以尝试一下,不是在相同的情况下,但它对我有用,我仍然使用它。这减少了应用程序使用的内存大小。它很容易创建和测试。

  1. 创建一个名为 clsMemory 的类并插入此代码:

     Imports System.Runtime.InteropServices
    
     Public Class clsMemory
    
     <DllImport("KERNEL32.DLL", EntryPoint:="SetProcessWorkingSetSize", SetLastError:=True, CallingConvention:=CallingConvention.StdCall)> _
     Friend Shared Function SetProcessWorkingSetSize(ByVal pProcess As IntPtr, ByVal dwMinimumWorkingSetSize As Integer, ByVal dwMaximumWorkingSetSize As Integer) As Boolean
     End Function
    
     <DllImport("KERNEL32.DLL", EntryPoint:="GetCurrentProcess", SetLastError:=True, CallingConvention:=CallingConvention.StdCall)>
     Friend Shared Function GetCurrentProcess() As IntPtr
     End Function
    
     Public Sub New()
         Dim pHandle As IntPtr = GetCurrentProcess()
         SetProcessWorkingSetSize(pHandle, -1, -1)
     End Sub
     End Class
    
  2. 在您的表单上创建一个按钮 btnCleanMemory 并插入此代码:

      Dim MemClass As New clsMemory()
      MemClass = Nothing
    

这是一个长镜头,但当应用程序使用大量内存时,只需单击该按钮,看看它是否适合您。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-06
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多