- Home /
Question by
$$anonymous$$ · Oct 07, 2015 at 03:06 PM ·
editormemorythreading
How to clear UnityEditor memory?
Tell me, please, how to clean up the memory occupied by the editor? I make game map asynchronously, and after stopping the build, editor does not give memory back. On the next startup everything is repeated, and finally i need to restart the editor, otherwise it becomes impossible to work because of the laaaaaags.
Or maybe I somehow incorrectly threading work?
Asynchronous worker:
using System;
using System.Threading;
using System.ComponentModel;
public delegate void AsyncWorkerHandler(AsyncWorkerArg e);
public class AsyncWorkerArg
{
public object Source;
public object Result;
}
public class AsyncWorker:IDisposable
{
public event Action WorkStarted;
public AsyncWorkerHandler DoWork;
public Action<float> ProgressChanged;
public Action<object> WorkCompleted;
private AsyncOperation _asyncOperation;
private readonly SendOrPostCallback _operationStarted;
private readonly SendOrPostCallback _progressChanged;
private readonly SendOrPostCallback _operationCompleted;
private Thread _thread;
public AsyncWorker()
{
_asyncOperation = AsyncOperationManager.CreateOperation(null);
_operationStarted = new SendOrPostCallback(AsyncOperationStarted);
_progressChanged = new SendOrPostCallback(AsyncProgressChanged);
_operationCompleted = new SendOrPostCallback(AsyncOperationCompleted);
}
public void WorkAsync(object source)
{
_thread = new Thread(Thread_work);
_thread.IsBackground = true;
_thread.Priority = ThreadPriority.Lowest;
_thread.Start(source);
}
private void Thread_work(object source)
{
this._asyncOperation.Post(_operationStarted, null);
var arg = new AsyncWorkerArg() { Source = source };
if (DoWork != null)
{
lock (DoWork)
{
DoWork(arg);
}
}
this._asyncOperation.Post(_operationCompleted, arg.Result);
}
public void ReportProgress(float progress)
{
this._asyncOperation.Post(_progressChanged, progress);
}
private void AsyncOperationStarted(object arg)
{
if (WorkStarted != null)
{
WorkStarted();
}
}
private void AsyncProgressChanged(object arg)
{
if (ProgressChanged != null)
{
ProgressChanged((float)arg);
}
}
private void AsyncOperationCompleted(object arg)
{
_thread.Abort();
if (WorkCompleted != null)
{
WorkCompleted(arg);
}
}
public void Dispose()
{
_thread.Abort();
WorkStarted -= WorkStarted;
DoWork -= DoWork;
ProgressChanged -= ProgressChanged;
WorkCompleted -= WorkCompleted;
}
}
Map generator without inessential:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
using PNetJson;
public class MapGenerator:IDisposable
{
private AsyncWorker _worker;
public GameMap Result;
public bool Completed { get; private set; }
public string State { get; private set; }
public float Progress { get; private set; }
private JSONValue _save;
public MapGenerator(int width, int height, int depth, GenerateType type)
{
Completed = false;
State = "cells";
Progress = 0f;
Result = GameObject.Instantiate<GameMap>(Global.MapPrefab);
Result.SetSize(width, height, depth);
_worker = new AsyncWorker();
_worker.DoWork = _worker_CreateCells;
_worker.ProgressChanged = _worker_ProgressChanged;
_worker.WorkCompleted = _worker_WorkCompleted;
_worker.WorkAsync(new object[] { width, height, depth, type });
}
void _worker_CreateCells(AsyncWorkerArg e)
{
//generating
}
void _worker_CreateLinks(AsyncWorkerArg e)
{
//generating
}
void _worker_FillMap(AsyncWorkerArg e)
{
//generating
}
void _worker_WorkCompleted(object result)
{
object[] res = (object[])result;
switch (State)
{
case "cells":
State = "links";
_worker.DoWork = _worker_CreateLinks;
_worker.WorkAsync(res);
break;
case "links":
switch ((GenerateType)res[1])
{
case GenerateType.OnlyTemplate:
Result.SetCells((MapCell[, ,])res[0]);
Completed = true;
break;
case GenerateType.FlatStone:
case GenerateType.RandomStone:
State = "filling";
_worker.DoWork = _worker_FillMap;
_worker.WorkAsync(res);
break;
case GenerateType.Load:
State = "filling";
_worker.DoWork = _worker_FillMapLoaded;
_worker.WorkAsync(new object[] { res[0], _save });
break;
}
break;
case "filling":
Result.CurrentLayer = (int)res[1];
Result.SetCells((MapCell[, ,])res[0]);
Completed = true;
break;
}
}
void _worker_ProgressChanged(float progress)
{
Progress = progress;
}
private int CheckProgress(ref int current, int preview, int max)
{
current ++;
float fcurrent = (float)current;
if ((fcurrent - preview) / max >= 0.01f)
{
_worker.ReportProgress(fcurrent / max);
return current;
}
return preview;
}
public void Dispose()
{
_worker.Dispose();
_worker = null;
Result = null;
_save = null;
}
public enum GenerateType : int
{
OnlyTemplate,
RandomStone,
FlatStone,
Load
}
}
How i invoke this:
public void NewGame()
{
StartCoroutine(GenerateWorld());
}
IEnumerator GenerateWorld()
{
using (var generator = new MapGenerator(Width, Height, Depth, MapGenerator.GenerateType.FlatStone))
{
foreach (var obj in MakeMap(generator)) yield return obj;
}
}
IEnumerable MakeMap(MapGenerator generator)
{
_realValue = 0f;
LoadingText.text = "Pre-generating...";
while (!generator.Completed)
{
switch (generator.State)
{
case "cells":
_realValue = generator.Progress * 0.2f;
LoadingText.text = "Making cells...";
break;
case "links":
_realValue = generator.Progress * 0.4f + 0.2f;
LoadingText.text = "Linking cells...";
break;
case "filling":
_realValue = generator.Progress * 0.35f + 0.6f;
LoadingText.text = "Generating surface...";
break;
}
yield return new WaitForSeconds(0.05f);
}
ScenesManager.Instance.Pop();
ScenesManager.Instance.Push(GameScene.GetInstance(generator.Result));
}
Comment
Your answer
Follow this Question
Related Questions
Editor crash after editing in a better computer 0 Answers
How do you stop multithreading in editor? 1 Answer
Editor Crashes when spawning 1k objects 2 Answers
Running out of memory upon re-import and update 0 Answers
Editor memory leak 0 Answers