Search Unity

Bug Player build hangs on blank screen; memory leak proceeds to eat up 95% system RAM

Discussion in 'Editor & General Support' started by alex_dossamer, Nov 23, 2021.

  1. alex_dossamer

    alex_dossamer

    Joined:
    Jun 19, 2018
    Posts:
    25
    [Copy-paste of case 1382261 since it's been a couple days and Unity devs aren't responding]

    This is a critically blocking problem; I was only able to find one similar error report: https://forum.unity.com/threads/windows-build-started-to-crash.893467/

    "Apparently, if you have serialized data in a singleton, you can not access it on declaration." (Unfortunately I have no singletons, but I do have a lot of serialized data.)

    An overview: I'm prototyping a generic boardgame system that relies extensively on serialized assets. In particular, level generation depends on reading out a string from a text file via a serialized text asset reference.

    If you open the main scene and click play in the editor, the game initializes fine.

    If you compile for either Windows 64bit or WebGL, the game doesn't manage to initialize. The profiler never records any frames, and the log terminates after the lines:

    "D3D11 device created for Microsoft Media Foundation video decoding.
    <RI> Initialized touch support.
    UnloadTime: 1.477500 ms"

    It's my sense that *after* UnloadTime in a normally-functioning build, resources start getting deserialized.

    The screen on Windows is blank; on WebGL, the loading bar is stuck; and very quickly RAM utilization rises close to 100% of what's available on the physical device. Windows gives no crash message, but WebGL (regardless of browser, desktop or mobile) reports via browser alert:

    abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value 2147418112, (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ") at jsStackTrace@http://localhost:49264/Build/WebGL.framework.js:2:16334
    stackTrace@http://localhost:49264/Build/WebGL.framework.js:2:16505
    abort@http://localhost:49264/Build/WebGL.framework.js:2:748
    abortOnCannotGrowMemory@http://localhost:49264/Build/WebGL.framework.js:2:17590
    @http://localhost:49264/Build/WebGL.wasm:wasm-function[51242]:0xf21875

    I've run the WebGL build on Edge and Firefox for Windows, and Firefox and Chrome for Android. The bug isn't platform dependent.

    My sense is that something is trying to deserialize during Unity's runtime initialization; it's failing, without freeing allocated memory; and then repeats over and over, allocating more memory until the program crashes out. Since there's no meaningful error data in the actual player log I'm at a loss for what to try next.

    Thank you for your help!
    -Alex
     
  2. alex_dossamer

    alex_dossamer

    Joined:
    Jun 19, 2018
    Posts:
    25
    Giving this a bump; have tested the editor project / made a new build on a desktop PC with significantly better specs, and still run into the memory leak specified above. If anyone has any pointers, help is much appreciated! Happy belated Thanksgiving to those in the US :)
     
  3. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    You have an infinite loop in "Board.HardDespawn" function. It happens to be an infinite loop only in builds because you have "Application.isEditor" check in there that makes it non-infinite in the editor.

    Generally, you should avoid "Application.isEditor" checks unless you want to do something extra in the editor (like do debug logging). Those checks can easily lead to bugs that only manifest in builds.

    Lastly, you should be able to diagnose this by attaching a debugger to a running player: https://docs.unity3d.com/Manual/ManagedCodeDebugging.html
     
  4. alex_dossamer

    alex_dossamer

    Joined:
    Jun 19, 2018
    Posts:
    25
    Thank you!! I had run the game with the profiler but didn't realize the debugger was separate (novice mistake).

    I suppose it was me misunderstanding lifecycle implementation details, the code being:

    Code (CSharp):
    1. public void HardDespawn()
    2.         {
    3.             // destroy not just listed entities but all children of transform
    4.             while (transform.childCount > 0)
    5.             {
    6.                 var c = transform.GetChild(0).gameObject;
    7.  
    8.                 if (Application.isEditor)
    9.                 {
    10.                     DestroyImmediate(c);
    11.                 }
    12.                 else
    13.                 {
    14.                     Destroy(c);
    15.                 }
    16.             }
    17.         }
    I didn't realize calling Destroy() on an object doesn't automatically trigger a transform's childCount to update (I presume that happens at the very end of the frame).

    First go at a work around was to swap the while loop with a for loop:
    Code (CSharp):
    1. for (int i = 0; i < transform.childCount; i++)
    But this actually doesn't work, either in the editor or in the build--none of the objects get destroyed. It seems like transform.childCount might initialize for the first time after the Awake() part of the frame lifecycle?

    Thank you so much, I really was stumped by this one!
     
  5. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    If you read the name - Destroy - it destroys the object. The alternative is DestroyImmediate, which suggests that Destroy doesn't do it immediately. If you read the documentation (https://docs.unity3d.com/ScriptReference/Object.Destroy.html), you'll see that it will Destroy the object at the end of the frame :). So yes, it will not change children. But they'll be gone the next time Update() is called.
     
    alex_dossamer likes this.