- Home /
www.texture dispose didn't work, causing memory leak
Hi, I wanna ask about www.texture. I use www.texture to load about 50 textures. Sometimes I destroy the mainTexture of that objects and sometimes I need to load it again (like paging system on webpage). Here's part of my code :
1. WWW www = new WWW(resourceName);
2. yield return www;
3. if (!loaded) {
4. if (www.error == null) {
5. temp = www.texture;
6. texHeight = temp.height;
7. texWidth = temp.width;
8. loaded = true;
9. }
10. else
11. Tex = FallbackTexture;
12.}
13.Tex = new Texture2D(texWidth, texHeight, TextureFormat.DXT1, false);
14.www.LoadImageIntoTexture(Tex);
15.www.Dispose();
At first load, I use variable "temp" to save www.texture, and tempHeight + tempWidth to save it's resolution. But at the second load I don't call that again, I only create new Texture2D from tempWidth and tempHeight. After that I dispose that www, but the problem is the memory won't free.
At the second load, it suppose to call the www.texture again, so the memory is increasing again and still it won't free after dispose.
I don't get this problem when I remark line 5-7 and use exact tempWidth and tempHeight (says 1024x768 manually). I don't know it's bug or maybe I got wrong using this kind of things.
Please help. Thanks!
Answer by HoMeBoYErik · Oct 24, 2014 at 06:34 PM
I recently faced the same problem. I was creating an scrollable image gallery in Unity, where images are downloaded in real-time from the a web server. On iOS devices I was reaching very fast the memory limit (with consequent app crash). That was caused due to a very big number of www objects leaved in the memory and never deleted or released. Also a very big number of Texture2D objects leaked. The main misunderstanding is considering a Texture2D like a variable of an object that self-contained the image information. Texture2D only point to a referenced asset so we need to create one before assigning to our GUI object. Without creating one we will overwrite the referenced asset in our project, leading to very crazy behaviour. So this the code that works for me on iOS and just use the minimum of memory
public void DownloadImage(string url)
{
StartCoroutine(coDownloadImage(url));
}
IEnumerator coDownloadImage(string imageUrl)
{
WWW www = new WWW( imageUrl );
yield return www;
thumbnail.mainTexture = new Texture2D(www.texture.width, www.texture.height, TextureFormat.DXT1, false);
www.LoadImageIntoTexture(thumbnail.mainTexture as Texture2D);
www.Dispose();
www = null;
}
A brief comment: You receive a url you will download the image from. Start the coroutine that manage the download Create the www object in the local scope yield waiting the download to complete Create a new Texture2D object/asset with parameters and assign to your final object mainTexture or what do you want Use the "www.LoadImageIntoTexture()" function to COPY the image inside the created asset (this is the fundamental part) Dispose and set to null the www object to prevent memory leaking or orphans
Hope it helps who will face the same problem.
An interesting lecture is this website where they implement a WebImageCache system to avoid re-downloading the same image many times.
I have found solution with other method. By using:
DestroyImmediate(www.texture);
DestroyImmediate(temp);
www.Dispose();
Resources.UnloadUnusedAssets();
with that code, the texture won't stay on ur memory.
Thank you @till, this solved my problem. I was having memory leaks after using Texture2D many times in the same scene. Just by calling Resources.UnloadUnusedAssets(); after loading the images the problem was solved. https://docs.unity3d.com/ScriptReference/Resources.UnloadUnusedAssets.html
I'm encountering the same in Windows, and none of these solutions work for me. Similar usage as others; a slideshow with images loaded off the hard drive rather than online. Each time SetImage is called, the app uses additional 100$$anonymous$$B or so of memory. Each of the images are only 8$$anonymous$$B. Dispose does not do anything. DestroyImmediate(www.texture) actually makes things worse.
void Start () {
GetComponent<Renderer>().material.mainTexture = new Texture2D(8192, 4096, TextureFormat.DXT1, false);
SetImage(0);
}
void SetImage(int index){
string url = "file://C:/Images/"+index.ToString ()+".jpg";
www = new WWW(url);
www.LoadImageIntoTexture(GetComponent<Renderer>().material.mainTexture as Texture2D);
//DestroyImmediate(www.texture);
www.Dispose();
www = null;
}
Hey silverfire330,
The solution worked perfectly for me. $$anonymous$$aybe on SetImage function
www = new WWW(url);
after that line I think you should add "yield" for ensuring that the file already downloaded.
Anyway, if you are just want to load texture from local directory, this solution should work for you. http://answers.unity3d.com/questions/623448/www-class-for-loading-local-texture-is-very-slow.html.
Sorry for out of topic, but I tradeoff my www loader to this new method. It very helpful for me, my textures work perfectly with almost no lagging (this method load image faster than using www).
Thanks so much for the reply, I really appreciate it. Unfortunately, even the file solution results in dramatic memory usage for me, and is not any faster than www. :-/ It seems like loading an (large) image into a texture is problematic, whether with www or File... I'll try with smaller ones to see if that's the cause, since you and everyone else has had success.
string url = "C:/Images/"+index+".jpg";
byte [] binaryImageData = System.IO.File.ReadAllBytes(url);
tex.LoadImage(binaryImageData);
GetComponent<Renderer>().material.mainTexture = tex;
Answer by PhaTeo · Sep 05, 2013 at 03:11 PM
I do believe, I have answer for this problem.
If you want to use WWW object for downloading texture.
You SHOULD NEVER USE popoerty WWW.texture. I think, that in this moment WWW instance, creates internal texture (something like new Texture2D()), that is returned to you.
However, this internal texture is not properly disposed and will remain in memory.
Not even WWW.Dispose() will work correctly.
You have to always use only WWW.LoadImageIntoTexture .
And be careful not to use .texture property even for testing if WWW carries the texture or to gain dimensions or any other information about texture!!!
In theory, you can use WWW.texture property. But once you call it, you are responsible, to calling Texture2D.Dispose(wwwTexture) on returnted result. Only then might be created texture properly removed from memory.
It's been some time but the problem of Textures not being culled still persists, collecting and disposing them manually, by destroying them, as suggested works well and got rid of my memory leak. $$anonymous$$ind you I am talking about Textures i created at runtime.
I just tried that i had
'Dispose' is not a member of 'UnityEngine.Texture2D'.
i wrote:
Texture2D.Dispose(www) ;
I have worked on this issue for 3-4 hours now and chacked 10 pages of solutions and i still have memory in Unity which stays full even when the program stops playing, so after 30 pictures i am at 1gb and if i stop playing i am at 9gb, and soon after it will crash.
$$anonymous$$y feeling is that something is up for Windows. It seems like Android and iOS apps don't have this problem, but after spending a few weeks banging my head against the wall with this, I'm fairly convinced that there is no solution for Windows. You will have runaway memory allocation when loading textures from a file or URL, no matter what. $$anonymous$$y solution was to simply stop doing it, unfortunately.
Uhm you have to destroy textures you don't use anymore. Textures never destroy themselfs. Only when you load a new scene or when you call UnloadUnusedAssets. Have you read @tills comment above?
In relation to the original code in question those lines should be at the end of the coroutine:
DestroyImmediate(temp);
www.Dispose();
// www = null;
// System.GC.Collect();
Resources.UnloadUnusedAssets();
The commented code might help as well since it would ensure that the www object is truly removed before we call UnloadUnusedAssets.
Your answer
![](https://koobas.hobune.stream/wayback/20220613104143im_/https://answers.unity.com/themes/thub/images/avi.jpg)