Unity c# 列出内存泄漏
Unity c# List memory leak
我在运行时分配纹理时遇到严重的内存泄漏。
当 useNewArray 为真时,任务管理器显示 Unity 的内存使用量增加了约 20 MB/秒。
完整的(183k 压缩)项目可以在这里下载:
https://goo.gl/axFJDs
这是我的代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class testMemory : MonoBehaviour {
public bool useNewList = false;
Texture2D newTexture;
public byte color;
List<Color> newColors;
List<byte> staticPixelColorsList;
Color tempColor = Color.white;
// Use this for initialization
void Start () {
newTexture = new Texture2D(0,0);
newColors = new List<Color>();
staticPixelColorsList = new List<byte>(120000);
GetComponent<Renderer>().material.mainTexture = newTexture;
}
// Update is called once per frame
void Update () {
// Make sure we're using different colors for every frame
color = (byte)((Time.time*255) % 255);
if(useNewList)
{
// This option causes a memory leak, but it's the one I need
// because I'm getting the texture data from an external source
int newWidth = Random.Range(200,400);
int newHeight = Random.Range(200,400);
// Create a new list each time
List<byte> newPixels = new List<byte>(newWidth * newHeight);
for(int i = 0; i < newWidth * newHeight; i++)
{
newPixels.Add ((byte)(color * i / 120000f));
}
setTexture(newPixels, newWidth, newHeight);
// Clear the list (yeah, right)
newPixels.Clear ();
}
else
{
// Use the same list, but assign new colors
for(int i = 0; i < 120000; i++)
{
staticPixelColorsList.Add ((byte)(color * i / 120000f));
}
setTexture(staticPixelColorsList, 300, 400);
staticPixelColorsList.Clear ();
}
}
void setTexture(List<byte> inputPixels, int inputWidth, int inputHeight)
{
newTexture.Resize(inputWidth, inputHeight);
float colorValue;
// Convert input value to Unity's "Color"
for(int n = 0; n < newTexture.width * newTexture.height ; n++)
{
colorValue = inputPixels[n] / 255.0f;
tempColor.r = tempColor.g = tempColor.b = colorValue;
newColors.Add (tempColor);
}
// Actually set the texture pixels
newTexture.SetPixels(newColors.ToArray());
newTexture.Apply();
newColors.Clear();
}
}
提前致谢
根据此 MSDN Article,List<T>.Clear
方法将 Count
属性 重置为 0 并释放对集合元素的所有引用。
但是,容量保持不变。因此,相同数量的内存保持分配状态。要释放这块内存,应该调用TrimExcess
方法,或者手动设置Capacity
属性
也许不用每次调用 Update
方法时都创建一个新的 newPixels
列表,您可以在函数外部创建此列表(可能在 class 声明中)并重新填充每次 Update
方法被调用?清除是可选的,因为每次调用时,内容都会被覆盖。这也可以提高性能,因为您的代码不必在每次更新结束时释放集合中的每个成员。
显然这是 Texture2D.Apply() 的错误。它是如此之深,Unity 的分析器没有显示泄漏,但外部工具显示了。 Unity 已经承认了这个问题并正在寻求解决方案。没有给出日期。感谢您的帮助:-)
我在运行时分配纹理时遇到严重的内存泄漏。
当 useNewArray 为真时,任务管理器显示 Unity 的内存使用量增加了约 20 MB/秒。
完整的(183k 压缩)项目可以在这里下载: https://goo.gl/axFJDs
这是我的代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class testMemory : MonoBehaviour {
public bool useNewList = false;
Texture2D newTexture;
public byte color;
List<Color> newColors;
List<byte> staticPixelColorsList;
Color tempColor = Color.white;
// Use this for initialization
void Start () {
newTexture = new Texture2D(0,0);
newColors = new List<Color>();
staticPixelColorsList = new List<byte>(120000);
GetComponent<Renderer>().material.mainTexture = newTexture;
}
// Update is called once per frame
void Update () {
// Make sure we're using different colors for every frame
color = (byte)((Time.time*255) % 255);
if(useNewList)
{
// This option causes a memory leak, but it's the one I need
// because I'm getting the texture data from an external source
int newWidth = Random.Range(200,400);
int newHeight = Random.Range(200,400);
// Create a new list each time
List<byte> newPixels = new List<byte>(newWidth * newHeight);
for(int i = 0; i < newWidth * newHeight; i++)
{
newPixels.Add ((byte)(color * i / 120000f));
}
setTexture(newPixels, newWidth, newHeight);
// Clear the list (yeah, right)
newPixels.Clear ();
}
else
{
// Use the same list, but assign new colors
for(int i = 0; i < 120000; i++)
{
staticPixelColorsList.Add ((byte)(color * i / 120000f));
}
setTexture(staticPixelColorsList, 300, 400);
staticPixelColorsList.Clear ();
}
}
void setTexture(List<byte> inputPixels, int inputWidth, int inputHeight)
{
newTexture.Resize(inputWidth, inputHeight);
float colorValue;
// Convert input value to Unity's "Color"
for(int n = 0; n < newTexture.width * newTexture.height ; n++)
{
colorValue = inputPixels[n] / 255.0f;
tempColor.r = tempColor.g = tempColor.b = colorValue;
newColors.Add (tempColor);
}
// Actually set the texture pixels
newTexture.SetPixels(newColors.ToArray());
newTexture.Apply();
newColors.Clear();
}
}
提前致谢
根据此 MSDN Article,List<T>.Clear
方法将 Count
属性 重置为 0 并释放对集合元素的所有引用。
但是,容量保持不变。因此,相同数量的内存保持分配状态。要释放这块内存,应该调用TrimExcess
方法,或者手动设置Capacity
属性
也许不用每次调用 Update
方法时都创建一个新的 newPixels
列表,您可以在函数外部创建此列表(可能在 class 声明中)并重新填充每次 Update
方法被调用?清除是可选的,因为每次调用时,内容都会被覆盖。这也可以提高性能,因为您的代码不必在每次更新结束时释放集合中的每个成员。
显然这是 Texture2D.Apply() 的错误。它是如此之深,Unity 的分析器没有显示泄漏,但外部工具显示了。 Unity 已经承认了这个问题并正在寻求解决方案。没有给出日期。感谢您的帮助:-)