【问题标题】:How can I reduce memory in VB.NET Windows application?如何减少 VB.NET Windows 应用程序中的内存?
【发布时间】:2010-09-24 07:44:15
【问题描述】:

我正在开发 VB.NET 多用户应用程序,每当我的任何表单打开时 - 内存都会增加,一段时间后会抛出 OutOfMemoryException

我正在开发 VB.net 2008 和 SqlServer 2005。 我已经使用了很多共享对象,所以第二次它的内存分配更少, 但是当表单关闭或不使用时我如何减少它。 我可以使用垃圾收集器或 Dispose 吗?如何使用此功能?

【问题讨论】:

    标签: vb.net memory out-of-memory


    【解决方案1】:

    您是否根据需要分离所有事件处理程序?这是 .NET 应用程序中内存泄漏的常见来源。

    您可以使用ANTS Memory Profiler 之类的工具来解决此问题,或者如果您更喜欢免费选项WinDbg+SOS 非常有用(但不那么容易使用)。

    【讨论】:

    • 那可能是问题所在。如果订阅者和发布者的生命周期相同,这不是问题,但是如果发布者保留所有订阅者也将保留,除非您分离处理程序。
    • 但我没有在我的项目中使用添加处理程序,所以我不需要使用删除处理程序。
    • 你还有什么要说的吗?
    • 请举个例子。
    • @KuldipMCA:很难从你的问题中看出你的应用程序是如何设计的,但如果你有一个 GUI,你不太可能没有任何事件处理程序。
    【解决方案2】:

    使用 .net 垃圾收集是一个自动过程,会清除内存中所有未使用的对象。

    在等待垃圾回收时,程序可能会“丢失”大量内存。

    通常您应该不理会垃圾收集器。它通常可以很好地决定何时打扫房子是值得的。

    但你可能希望不时强迫它的手。

    有一个非常简单的调用来清除垃圾回收。

    GC.Collect()

    希望这会有所帮助。

    虽然,您可能还有其他一些问题要解决内存不足异常。

    您是否偶然处理图像?

    【讨论】:

    • 很少建议调用 GC.Collect。
    • 同意。但有时它可能很有用,就像我说的可能是其他问题。
    • 如前所述,您可能还有另一个问题,因为垃圾收集通常很擅长清理。我会尝试按照 Brian Rasmussen 的建议去做。
    【解决方案3】:

    试试这个代码释放内存:

    首先声明这个函数:

    Private Declare Function SetProcessWorkingSetSize Lib "kernel32.dll" (ByVal hProcess As IntPtr, ByVal dwMinimumWorkingSetSize As Int32, ByVal dwMaximumWorkingSetSize As Int32) As Int32
    

    这就是它的用法:

    Friend Sub ReleaseMemory()
        Try
            GC.Collect()
            GC.WaitForPendingFinalizers()
            If Environment.OSVersion.Platform = PlatformID.Win32NT Then
                SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1)
            End If
        Catch ex As Exception
            LogError(ex.ToString())
        End Try
    End Sub
    

    【讨论】:

      【解决方案4】:

      确保在不再需要对象时删除对对象的所有引用。 (或所有对父对象的引用)

      如果您的一个活动表单仍然使用您不需要的对象,垃圾收集器将假定您仍然需要它并且不会将其从内存中删除。

      不要忘记在需要时调用 .Dispose()。

      有一些很棒的工具可以提示您的内存问题在哪里。

      【讨论】:

        【解决方案5】:

        最好的:

        公开课FreeMemory 私有声明函数 SetProcessWorkingSetSize Lib "kernel32.dll" (_ ByVal 进程 As IntPtr, _ ByVal minimumWorkingSetSize As Integer, _ ByVal maximumWorkingSetSize As Integer) As Integer

        Public Shared Sub FlushMemory()
            GC.Collect()
            GC.WaitForPendingFinalizers()
            If (Environment.OSVersion.Platform = PlatformID.Win32NT) Then
                SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1)
            End If
        End Sub
        

        结束类

        【讨论】:

        • 所以你发布了一个几乎重复的答案(唯一的区别是你删除了一个catch),但代码格式只有稍微好一点?
        猜你喜欢
        • 2016-11-09
        • 1970-01-01
        • 2010-10-02
        • 1970-01-01
        • 1970-01-01
        • 2010-09-28
        • 2020-12-24
        • 1970-01-01
        • 2010-11-23
        相关资源
        最近更新 更多