Что за дела? Я хочу узнать причину, почему это происходит и как очистить память полностью, не перезагружая сцену.
Я думал, может пул поломанный. Для чистоты теста построил отдельный чистый проект с простым скриптом. Никаких других ассетов, текстур и т.д. не используется, только чистые дефолтные кубы, упакованные в два префаба. Один спаунится обычно, по ссылке на GameObject в скрипте, второй с помощью Resources.Load. Я думал, может будет разница, но разницы нет.
Итого чистую сцену могу довести до 1.5 Гб занятой памяти, хотя ни единого объекта в сцене нет. Нужно предварительно наспаунить несколько десятков тысяч объектов, а потом уничтожить их и повторить несколько раз.
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test
{
public class PrefomanceMemorySpawnDestroyObjects : MonoBehaviour
{
int cycles = 1000;
public GameObject prefab;
List<GameObject> list = new List<GameObject>();
private void Update()
{
if (Input.GetKey(KeyCode.Alpha1))
{
SpawnPrefab();
}
if (Input.GetKey(KeyCode.Alpha2))
{
SpawnResource();
}
if (Input.GetKeyDown(KeyCode.Alpha3))
{
DestroyAll();
}
if (Input.GetKeyDown(KeyCode.Alpha4))
{
ClearMemory();
}
}
void SpawnPrefab()
{
for(int i = 0; i < cycles; i++)
{
GameObject go = Instantiate(prefab);
Vector3 pos = new Vector3(Random.Range(-100f, 100f), Random.Range(-100f, 100f), Random.Range(-100f, 100f));
go.transform.position = pos;
list.Add(go);
}
}
void SpawnResource()
{
for (int i = 0; i < cycles; i++)
{
GameObject go = GameObject.Instantiate(Resources.Load("1", typeof(GameObject))) as GameObject;
Vector3 pos = new Vector3(Random.Range(-100f, 100f), Random.Range(-100f, 100f), Random.Range(-100f, 100f));
go.transform.position = pos;
list.Add(go);
}
}
void DestroyAll()
{
foreach(GameObject go in list)
{
Destroy(go);
}
list = new List<GameObject>();
}
void ClearMemory()
{
Resources.UnloadUnusedAssets();
System.GC.Collect();
}
}
}
using System.Collections.Generic;
using UnityEngine;
namespace Test
{
public class PrefomanceMemorySpawnDestroyObjects : MonoBehaviour
{
int cycles = 1000;
public GameObject prefab;
List<GameObject> list = new List<GameObject>();
private void Update()
{
if (Input.GetKey(KeyCode.Alpha1))
{
SpawnPrefab();
}
if (Input.GetKey(KeyCode.Alpha2))
{
SpawnResource();
}
if (Input.GetKeyDown(KeyCode.Alpha3))
{
DestroyAll();
}
if (Input.GetKeyDown(KeyCode.Alpha4))
{
ClearMemory();
}
}
void SpawnPrefab()
{
for(int i = 0; i < cycles; i++)
{
GameObject go = Instantiate(prefab);
Vector3 pos = new Vector3(Random.Range(-100f, 100f), Random.Range(-100f, 100f), Random.Range(-100f, 100f));
go.transform.position = pos;
list.Add(go);
}
}
void SpawnResource()
{
for (int i = 0; i < cycles; i++)
{
GameObject go = GameObject.Instantiate(Resources.Load("1", typeof(GameObject))) as GameObject;
Vector3 pos = new Vector3(Random.Range(-100f, 100f), Random.Range(-100f, 100f), Random.Range(-100f, 100f));
go.transform.position = pos;
list.Add(go);
}
}
void DestroyAll()
{
foreach(GameObject go in list)
{
Destroy(go);
}
list = new List<GameObject>();
}
void ClearMemory()
{
Resources.UnloadUnusedAssets();
System.GC.Collect();
}
}
}
Если хотите протестировать, вот unitypackage: https://www.dropbox.com/s/agw1iyxuv3iv738/MemTest.unitypackage?dl=0
Можете еще сборку потестить, в диспетчере задач все в реальном эксперименте можно увидеть. Создайте столько объектов, пока сборка не займет 2 ГБ памяти, а потом нажмите 3- увидите, что теперь где-то 1 гб занимает сборка, хотя изначально было в районе 70-100 мб.
(цифры 1 или 2- спаун, 3- удаление, 4- оптимизация)- https://www.dropbox.com/s/f3w1erpd4zv0nsf/MemoryTest.rar?dl=0