什么导致Unity内存泄漏?

时间:2018-03-16 08:18:28

标签: c# unity3d

我使用以下代码在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;

1 个答案:

答案 0 :(得分:3)

见:

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

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

通过执行此操作,当摄像机图像高度/宽度发生变化导致frame.SetPixels(wct.GetPixels());失败并出现异常时,您可能会遇到新问题。要解决此问题,请检查相机纹理大小何时更改,然后自动调整frame纹理的大小。此检查应在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();
}