aCu*_*ria 3 c# unity-game-engine
我在使用以下代码时遇到了 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;
Run Code Online (Sandbox Code Playgroud)
看到这个:
Texture2D frame = new Texture2D(wct.width, wct.height);
Run Code Online (Sandbox Code Playgroud)
您Texture2D几乎每帧或何时都在创建新的didUpdateThisFrame 。这是非常昂贵的,而且大部分时间甚至没有被 Unity 释放。您只需要创建一个Texture2D然后在Update函数中重新使用它。使frame变量成为全局变量,然后在函数中初始化一次Start。
通过这样做,当相机图像高度/宽度更改导致frame.SetPixels(wct.GetPixels());失败并出现异常时,您可能会遇到新问题。要解决此问题,请检查相机纹理大小何时发生变化,然后自动调整frame纹理大小。此检查应在 Update 函数之前完成frame.SetPixels(wct.GetPixels());。
if (frame.width != wct.width || frame.height != wct.height)
{
frame.Resize(wct.width, wct.height);
}
Run Code Online (Sandbox Code Playgroud)
您的最终代码应如下所示:
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();
}
Run Code Online (Sandbox Code Playgroud)