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

Unity中更换UI.Image.Sprite后如何释放旧截图的RAM内存?

解决Unity截图内存未释放问题

每次执行截图代码后旧资源堆积,核心原因是未主动销毁旧的Texture2D和Sprite对象,Unity的GC不会自动回收这些未被销毁的Unity原生资源。以下是具体解决方案:

1. 替换时销毁旧资源

在类中保存旧的Sprite和Texture引用,每次生成新截图前先销毁旧资源:

private Sprite _prevScreenshotSprite;
private Texture2D _prevScreenshotTexture;

public void UpdateScreenShot()
{
    // 清理旧资源
    if (_prevScreenshotSprite != null)
    {
        Destroy(_prevScreenshotSprite);
        _prevScreenshotSprite = null;
    }
    if (_prevScreenshotTexture != null)
    {
        Destroy(_prevScreenshotTexture);
        _prevScreenshotTexture = null;
    }

    // 生成并设置新截图
    _prevScreenshotTexture = screenshotHandler.TakeScreenshot();
    _prevScreenshotSprite = Sprite.Create(_prevScreenshotTexture, new Rect(0, 0, Screen.width, Screen.height), Vector2.zero);
    image.sprite = _prevScreenshotSprite;
}

注意:必须使用Destroy()方法销毁Unity对象,仅将引用置空无法释放内存。

2. 复用Texture2D(根源优化)

不要每次新建Texture2D,初始化一个可复用的Texture2D,后续直接更新像素:

private Texture2D _reusableTexture;

// 在初始化时调用(比如Start方法)
private void Start()
{
    _reusableTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);
}

// 修改截图方法为复用模式
public Texture2D TakeReusableScreenshot()
{
    _reusableTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
    _reusableTexture.Apply();
    return _reusableTexture;
}

这样每次截图都复用同一块内存,不会产生新的资源堆积,同时减少GC压力。

3. 手动触发GC(按需使用)

如果内存压力大,可在替换截图后手动触发GC,但避免频繁调用(会导致卡顿):

// 在销毁旧资源、设置新截图后执行
System.GC.Collect();

4. 销毁对象时清理资源

在脚本所在对象被销毁时,确保所有持有的资源都被销毁:

private void OnDestroy()
{
    if (_prevScreenshotSprite != null) Destroy(_prevScreenshotSprite);
    if (_prevScreenshotTexture != null) Destroy(_prevScreenshotTexture);
    if (_reusableTexture != null) Destroy(_reusableTexture);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:52:57