You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual Studio VB.NET窗体项目System.OutOfMemoryException问题求助

解决VB.NET PictureBox切换图片时的System.OutOfMemoryException异常

问题描述

每次运行Visual Studio中的VB.NET窗体项目时,都会触发System.OutOfMemoryException异常。项目用于实现PictureBox切换不同广告图片的功能,尝试将图片格式从.png改为.jpg后问题依然存在。

原代码

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Dim gen As Random = New Random()

    Dim choice As Integer = gen.Next(0, 4)
    If choice = 0 Then
        PictureBox1.Image = Image.FromFile("Screenshot 2023-03-25 102759.jpg")
    ElseIf choice = 1 Then
        PictureBox1.Image = Image.FromFile("ad2.jpg")
    ElseIf choice = 2 Then
        PictureBox1.Image = Image.FromFile("ad4.jpg")
    Else
        PictureBox1.Image = Image.FromFile("ad5.jpg")
    End If
End Sub

堆栈跟踪信息

StackTrace
   at System.Drawing.Image.FromFile(String filename, Boolean useEmbeddedColorManagement)
   at System.Drawing.Image.FromFile(String filename)
   at Word_game_prototype.Form1.Timer1_Tick(Object sender, EventArgs e) in C:\Visual studio (delete this junk)\Word game prototype\Word game prototype\Form1.vb:line 20
   at System.Windows.Forms.Timer.OnTick(EventArgs e)
   at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
   at Word_game_prototype.My.MyApplication.Main(String[] Args) in :line 83

问题根源

  1. 未释放旧图片资源:每次Timer触发时直接赋值新的Image对象,旧的Image资源未被释放,非托管内存持续占用,多次触发后引发内存不足。
  2. 重复从文件加载图片:每次都从磁盘读取图片,既浪费IO资源,也加剧内存占用。
  3. 重复创建Random实例:每次Tick都新建Random对象,可能导致随机数重复,但不是内存异常的直接原因。

解决方案

核心优化点

  • 提前加载所有图片到内存,避免重复读取文件
  • 切换图片时释放旧的Image资源
  • 将Random声明为类级别变量,避免重复创建

修改后的完整代码

' 窗体级别变量,存储所有图片和随机数生成器
Private images As List(Of Image) = New List(Of Image)()
Private rand As Random = New Random()

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ' 窗体加载时一次性加载所有图片
    images.Add(Image.FromFile("Screenshot 2023-03-25 102759.jpg"))
    images.Add(Image.FromFile("ad2.jpg"))
    images.Add(Image.FromFile("ad4.jpg"))
    images.Add(Image.FromFile("ad5.jpg"))
End Sub

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    ' 释放当前PictureBox中的旧图片资源
    PictureBox1.Image?.Dispose()
    
    ' 随机选择一张图片赋值
    Dim choice As Integer = rand.Next(0, images.Count)
    PictureBox1.Image = images(choice)
End Sub

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    ' 窗体关闭时释放所有加载的图片资源
    For Each img In images
        img.Dispose()
    Next
    images.Clear()
End Sub

额外注意事项

  • 确保图片文件路径正确,若图片是项目嵌入资源,可改用Assembly.GetExecutingAssembly().GetManifestResourceStream方式加载,避免文件路径依赖。
  • 若图片尺寸过大,可考虑在加载时压缩图片分辨率,进一步减少内存占用。

内容的提问来源于stack exchange,提问作者Highlight Productions

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 00:05:01