Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

GetPixels Leak / Bug?

Discussion in 'Scripting' started by NathanWarden, Sep 25, 2008.

  1. NathanWarden

    NathanWarden

    Joined:
    Oct 4, 2005
    Posts:
    663
    Hey all,

    Can somebody confirm this for me. If you use a Texture2D.GetPixels(mipmap) call and don't have a SetPixels to go along with it, the memory will not be released... here's the code I have just as a quick test.

    If you have a 1024 x 1024 texture in there within a few minutes your system should come to a crawl... and your ram usage will go to about 1.5 GB with an empty scene with 1 object with this script attached.

    Am I missing something?

    Why wouldn't the local color arrays be dropped from RAM?

    Any suggestions on how to prevent this?

    Code (csharp):
    1.  
    2. var theTexture : Texture2D;
    3. var theTexture2 : Texture2D;
    4.  
    5.  
    6. function DoIt ( aTexture : Texture2D, texture2 : Texture2D ) {
    7.     var thePixels : Color[] = aTexture.GetPixels(0);
    8.     var thePixels2 : Color[] = texture2.GetPixels(0);
    9.  
    10.     aTexture.SetPixels(thePixels, 0);
    11.     aTexture.Apply();
    12. }
    13.  
    14.  
    15. function Update() {
    16.     DoIt (theTexture, theTexture2);
    17. }
    18.  
     
  2. NathanWarden

    NathanWarden

    Joined:
    Oct 4, 2005
    Posts:
    663
    Okay, so I was wrong it does it with Texture2D.SetPixels too. I left Safari open for about ten minutes. It was fine and then the RAM usage just took off like a rocket. I have it to be able to run in the background too, so that isn't the reason for the sudden increase... hmmm? :)

    Code (csharp):
    1.  
    2. var theTexture : Texture2D;
    3. //var theTexture2 : Texture2D;
    4.  
    5.  
    6. //function DoIt ( aTexture : Texture2D, texture2 : Texture2D ) {
    7. function DoIt ( aTexture : Texture2D ) {
    8.     var thePixels : Color[] = aTexture.GetPixels(0);
    9. //  var thePixels2 : Color[] = texture2.GetPixels(0);
    10.  
    11.     aTexture.SetPixels(thePixels, 0);
    12.     aTexture.Apply();
    13. }
    14.  
    15.  
    16. function Update() {
    17. //  DoIt (theTexture, theTexture2);
    18.     DoIt (theTexture);
    19. }
    20.  
     
  3. GargerathSunman

    GargerathSunman

    Joined:
    May 1, 2008
    Posts:
    1,571
    I don't know.... I think filling an array of size 1024 x 1024 every frame could do that as well.....

    From the description, it sounds like it's getting you an array of the individual pixel colors, and that texture is pretty big. If you're filling that array once a frame, that could be a pretty large load.

    Or, are you saying that the memory isn't impacted when you setpixels for both of them? It's not that clear whether you've tested that already.
     
  4. NathanWarden

    NathanWarden

    Joined:
    Oct 4, 2005
    Posts:
    663
    Okay, here's the new code... it doesn't seam to leak at all when using only one texture/pixel array, but, when using two like the following code, it leaks like crazy, can I only use one array at a time?

    It would be really nice to have a manual garbage collection system available, but, I guess that's a JScript problem and not a Unity problem... I guess. Or is there one hidden away somewhere that someone knows about. :)


    Code (csharp):
    1.  
    2. var theTexture1 : Texture2D;
    3. var theTexture2 : Texture2D;
    4.  
    5.  
    6. function DoIt () {
    7.     var thePixels1 : Color[] = theTexture1.GetPixels(0);
    8.     var thePixels2 : Color[] = theTexture2.GetPixels(0);
    9.  
    10.     theTexture1.SetPixels(thePixels1, 0);
    11.     theTexture1.Apply();
    12.  
    13.     theTexture2.SetPixels(thePixels2, 0);
    14.     theTexture2.Apply();
    15. }
    16.  
    17.  
    18. function Update() {
    19.     DoIt ();
    20. }
    21.  
     
  5. MuseGames

    MuseGames

    Joined:
    Mar 19, 2008
    Posts:
    98
    You can tell the Mono garbage collector to run by calling
    Code (csharp):
    1. System.GC.Collect();
    Note, however, that doing this doesn't always seem to make Unity release that memory back to the OS.
     
  6. NathanWarden

    NathanWarden

    Joined:
    Oct 4, 2005
    Posts:
    663
    Thanks Jormungandr!

    That seams to work really great! Like you said, it seams to miss some occasionally, but, it seams pretty rare, so, it's no big deal.

    Thanks again,
    You're the man,
    Nathan