- Home /
Marching cubes Memory Leak
Ok so as titled I am generating a 5 x 5 grid of terrain objects that have perlin noise on them. The problem im having is the textures I generate on these blocks are somehow never deleted in memory. I thought that destroying the game object the texture is on would remove it from memory. Anyway Im not sure what im doing wrong here. This is the code im using to generate each block.
public class GroundSetup : MonoBehaviour {
public float[,] heights;
public float test;
public float test2;
public float scrollX;
public float scrollY;
Dictionary<int,float> placersx = new Dictionary<int,float> ();
Dictionary<int,float> placersz = new Dictionary<int,float> ();
Dictionary<int,Vector3> pos = new Dictionary<int,Vector3> ();
Dictionary<int,GameObject> objects = new Dictionary<int,GameObject > ();
int pkeyx = 0;
int pkeyz = 0;
int objectCount = 0;
Terrain terr;
float StartingOffset = 50000;
GameObject tree;
Loader loader;
Texture2D grass;
Texture2D grassnorm;
Texture2D snow;
Texture2D snownorm;
Texture2D sand;
Texture2D sandnorm;
States statesScript;
GameObject hoodie;
// Use this for initialization
void Start () {
}
here is the part of the class where I put textures on the terrain
public void SetupGround(){
sand = loader.getsand ();
sandnorm = loader.getsandN ();
grass = loader.getgrass ();
grassnorm = loader.getgrassN ();
snow = loader.getsnow ();
snownorm = loader.getsnowN ();
SplatPrototype[] terrainTexture = new SplatPrototype[1];
terrainTexture [0] = new SplatPrototype ();
if (GetVert(60,60) < .4) {
terrainTexture [0].texture = (Texture2D)Resources.Load ("textures/sand");
terrainTexture [0].normalMap = (Texture2D)Resources.Load ("textures/sandnormal");
terr.materialType = Terrain.MaterialType.Custom;
}
if (GetVert(60,60) >= .4 & GetVert(60,60) < .8 ) {
terrainTexture [0].texture = (Texture2D)Resources.Load ("textures/grass");
terrainTexture [0].normalMap = (Texture2D)Resources.Load ("textures/grassnormal");
terr.materialType = Terrain.MaterialType.BuiltInStandard;
}
if (GetVert(60,60) >= .8) {
terrainTexture [0].texture = (Texture2D)Resources.Load ("textures/snow");
terrainTexture [0].normalMap = (Texture2D)Resources.Load ("textures/snownormal");
terr.materialType = Terrain.MaterialType.Custom;
}
terr.materialTemplate = (Material)Resources.Load ("materials/sand");
terr.basemapDistance = 1200f;
terrainTexture [0].tileSize = new Vector2 (10, 10);
terr.terrainData.splatPrototypes = terrainTexture;
Then when the block is no longer needed I call this
public void DeleteGround (){ foreach(KeyValuePair obj in objects){
Destroy(obj.Value);
}
Destroy (gameObject);
}
Do I need to destroy the terrain or the textures themselves? also Ive found that even with all this code commented out the textures still build up in the not saved category in the profiler. Any word of help or general cleanup tips would be greatly appreciated. Thank you.
I'm still a bit fuzz on Unity memory management, so I'm not sure if this will actually resolve the issue but here is a tidbit that helped me a lot... Texture inherits from Unity.Object, so you should be able to use the static Object.Destory(Object) method to remove the textures from memory
UnityEngine.Object.Destroy(textureToDestroy);
ok I tried adding these lines to the cleanup script.
public void DeleteGround (){
foreach($$anonymous$$eyValuePair<int,GameObject> obj in objects){
Destroy(obj.Value);
}
Object.Destroy (sand);
Object.Destroy (sandnorm);
Object.Destroy (snownorm);
Object.Destroy (snow);
Object.Destroy (grass);
Object.Destroy (grassnorm);
Destroy (gameObject);
}
as you can see there are a lot of destroy commands. this actually still somehow leaves all these textures in memory despite causing massive lag when it attempts to remove them. I am positive these are the textures being duplicated and left in memory because when I comment them out the memory leak is half as bad.
Is there some way to reference just 1 texture object for each texture and send that object to each terrain block. I thought it was a given that I would not want thousands of duplicates of the same texture.
how should I be loading these textures to not cause duplicates.
If you are adding the texture to the objects in your dictionary,I'd think you would want those Destroys commands inside the loop, to destroy the texture on each object.
Regarding using only texture references, rather than instances: yes that would make sense.
I see you load sand with
sand = loader.getsand (); // I assume this loads the resource
but then later on you use :
terrainTexture [0].texture = (Texture2D)Resources.Load ("textures/sand");
Why do you NOT use?:
terrainTexture [0].texture = sand;
I would check the dictionaries, does their size stay constant or continuously increase?
O wow thank you glurth. I meant to do that but I have just been looking at this way to long I guess. The dictionaries are made a certain size then deleted when the object is deleted. destroying a game object does delete the objects from the scripts attached doesn't it? Or do I need to specify to remove those as well? Anyway I made the corrections and I am still destroying each texture. However They are still piling up. Is there a way to use the same object each time I apply a texture. Here is a screen shot from the profiler of the issue.
Answer by ODINKONG · Apr 04, 2015 at 03:34 AM
Ok I think I got it. There are only ever 25 textures at one time now. Here is what I did.
first Glurth corrected some of the mistakes in my code, then I realized the textures were linked to a terrain data object that wasn't getting destroyed with the game object it was on. So I explicitly destroyed that. Then the program still wasn't cleaning up the textures so I had to make a class that calls these two guys like so.
void Update () {
if (Time.frameCount % 30 == 0)
{
Resources.UnloadUnusedAssets();
System.GC.Collect();
}
This is a hairy solution. If anyone has a better one I would love to hear it. Like for example some how just not creating all these texture objects.
Your answer
![](https://koobas.hobune.stream/wayback/20220613192117im_/https://answers.unity.com/themes/thub/images/avi.jpg)