繁体   English   中英

什么导致Unity内存泄漏?

[英]What causes Unity Memory Leaks?

我在使用以下代码时遇到了 Unity 内存泄漏:

行为:在运行时,Unity 最终使用 > 64GB 的 RAM 并崩溃(这就是这台机器所拥有的)

场景:我的场景中只有一架飞机,代码如下。

我该如何解决? 我不认为我想要这里的弱引用(或者至少在 C++ 中我不会在这种情况下使用weak_ptr,也许是unique_ptr)。 我只想在对象超出范围时释放内存。

void Start () {
    frameNumber_ = 0;

    // commented code leaks memory even if update() is empty
    //WebCamDevice[] devices = WebCamTexture.devices;
    //deviceName = devices[0].name;
    //wct = new WebCamTexture(deviceName, 1280, 720, 30);
    //GetComponent<Renderer>().material.mainTexture = wct;
    //wct.Play();

    wct = new WebCamTexture(WebCamTexture.devices[0].name, 1280, 720, 30);
    Renderer renderer = GetComponent<Renderer>();
    renderer.material.mainTexture = wct;
    wct.Play();
}

// Update is called once per frame
// This code in update() also leaks memory
void Update () {
    if (wct.didUpdateThisFrame == false)
        return;

    ++frameNumber_;

    Texture2D frame = new Texture2D(wct.width, wct.height);
    frame.SetPixels(wct.GetPixels());
    frame.Apply();

    return;

看到这个:

Texture2D frame = new Texture2D(wct.width, wct.height);

您几乎每一帧或当didUpdateThisFrame为真时didUpdateThisFrame新的Texture2D 这是非常昂贵的 ,大部分时间甚至没有被Unity释放。 您只需要创建一个Texture2D然后在Update函数中重复使用它。 使frame变量成为全局变量,然后在Start函数中初始化它一次


通过这样做,当相机图像高度/宽度改变导致frame.SetPixels(wct.GetPixels());时,您可能会遇到新问题frame.SetPixels(wct.GetPixels()); 因例外而失败。 要解决此问题,请检查相机纹理大小何时更改,然后自动调整frame纹理的大小。 此检查应在frame.SetPixels(wct.GetPixels());之前的Update函数中完成frame.SetPixels(wct.GetPixels());

if (frame.width != wct.width || frame.height != wct.height)
{
    frame.Resize(wct.width, wct.height);
}

您的最终代码应如下所示:

int frameNumber_ = 0;
WebCamTexture wct;
Texture2D frame;

void Start()
{
    frameNumber_ = 0;

    wct = new WebCamTexture(WebCamTexture.devices[0].name, 1280, 720, 30);
    Renderer renderer = GetComponent<Renderer>();
    renderer.material.mainTexture = wct;
    wct.Play();

    frame = new Texture2D(wct.width, wct.height);
}

// Update is called once per frame
// This code in update() also leaks memory
void Update()
{
    if (wct.didUpdateThisFrame == false)
        return;

    ++frameNumber_;

    //Check when camera texture size changes then resize your frame too
    if (frame.width != wct.width || frame.height != wct.height)
    {
        frame.Resize(wct.width, wct.height);
    }

    frame.SetPixels(wct.GetPixels());
    frame.Apply();
}

古老的话题,但我发现了一些有趣的东西。 我曾经在我的代码中有这个:

            downloadedTexture = DownloadHandlerTexture.GetContent(www);
        m_PictureScreen.GetComponent<RawImage>().texture = downloadedTexture;

这导致了内存泄漏的巨大问题,应用程序每次迭代都会超过 8GB。 我的情况每天可能会增加数千个文件。 我之前使用这一行解决了它:

Texture2D.Destroy(m_PictureScreen.GetComponent<RawImage>().texture);

不知道它是如何工作的,而且现在不存在内存泄漏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM