Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Large memory cannot be reclaimed

Discussion in 'Editor & General Support' started by NeverMore_, Jan 14, 2022.

  1. NeverMore_


    Apr 16, 2021
    We have a large json file and after multiple deserialization there is a memory leak. I began to suspect that it was a problem with the json library(newtonsoft.json,litjson,utf8json), but it still appeared after replacing a few. So I guess whether it may be caused by too large allocated memory. Through the following code, there is indeed a situation where the memory cannot be released. Why does this happen and how to fix it. Of course, native memory can be allocated through C++, but the cost is too high. I hope the official can give some suggestions and explain the principle.

    The editor is normal, there will be problems after packaging the exe

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    4. public class GCTest : MonoBehaviour
    5. {
    6.     const int DefaultSize = 300;
    8.     int MemorySize = DefaultSize;
    9.     // Start is called before the first frame update
    10.     void Start()
    11.     {
    12.         var strs = Environment.GetCommandLineArgs();
    13.         if (strs.Length == 2)
    14.         {
    15.             if (!int.TryParse(strs[1], out MemorySize))
    16.                 MemorySize = DefaultSize;
    17.         }
    18.     }
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.         if (Input.GetKeyDown(KeyCode.Space))
    24.         {
    25.             var bytes = new byte[1024 * 1024 * MemorySize];
    26.         }
    28.         if (Input.GetKeyDown(KeyCode.KeypadEnter))
    29.         {
    30.             Debug.LogError("Gc");
    31.             GC.Collect();
    32.         }
    33.     }
    34. }
  2. MartinTilo


    Unity Technologies

    Aug 16, 2017
    The object will be collected but the Managed Heap will keep it's expanded state for a moment longer, keeping the allocated space ready to be reused by new objects if needed. If this space isn't reused, it will be released to the OS again during a subsequent GC.Collect(). When exactly is an implementation detail you shouldn't rely on but at the moment, every 6th GC.Collect cycle should release such memory. You can also investigate this with the Memory Profiler. The empty managed space should show up in the bar diagrams and on the Fragmentation page.
  3. NeverMore_


    Apr 16, 2021
    When I did the test, GC.Collect() was called far more than six times, but the memory could not fall. And when I allocate 300m again, the memory will go up. I checked through the Memory Profiler, and there are indeed several 300m pieces of memory, and I can't find a reference to it. So how should I solve it in this case, because our json data is created by the user, I can't control its size, so it is easy to generate large memory allocation during deserialization.

    Attached Files: