Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Resolved MemoryProfiler: Jagged array may not be collected in memory captures

Discussion in 'Profiler Previews' started by pw_prg_yinchao, Apr 14, 2021.

  1. pw_prg_yinchao

    pw_prg_yinchao

    Joined:
    Feb 14, 2020
    Posts:
    18
    Hi there, I found jagged array (T[][]) may not be collected in memory captures.

    Test codes are something like:
    Code (CSharp):
    1. public class TestComponent : MonoBehaviour
    2. {
    3.     ...
    4.     private TestClass[] array1 =
    5.     {
    6.         new TestClass(),
    7.     };
    8.     private TestClass[][] array2 =
    9.     {
    10.         new [] {new TestClass(), null},
    11.         null,
    12.     };
    13.     ...
    14. }
    Then managed object
    array2
    and managed type
    TestClass[][]
    not found in captured snapshot (using Unity 2019.4.5f1 + com.unity.memoryprofiler@0.2.9-preview.1).
     
    Peter77 likes this.
  2. pw_prg_yinchao

    pw_prg_yinchao

    Joined:
    Feb 14, 2020
    Posts:
    18
    And, managed object of type
    TestClass[]
    inside
    array2
    also not found.
     
  3. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,620
  4. pw_prg_yinchao

    pw_prg_yinchao

    Joined:
    Feb 14, 2020
    Posts:
    18
    Alright, I found it has been fixed in 2019.4.10:
    https://unity3d.com/unity/whats-new/2019.4.10
     
    MartinTilo and Peter77 like this.
  5. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,461
    Yes, the package can't fix everything as the editor and runtime also have quite some backend code to report the data, so updating to the latest Editor patch version and latest package version should usually be the first thing to try when hitting any bugs with it, as we are basically unaware of any bugs with it at the moment.
     
  6. pw_prg_yinchao

    pw_prg_yinchao

    Joined:
    Feb 14, 2020
    Posts:
    18
    Thank you for the reply!

    But I found another question: it seems that interned strings, including literals and strings passed to
    string.Intern()
    , neither be collected. Is this expected? Or a known issue?
    For me, it is unexpected. Because these strings should be on the heap, and contribute to the total size of managed heap, right?
     
    Last edited: Apr 19, 2021
  7. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,461
    That's how Interned strings work in C#, also see the Microsoft Docs on this:
     
    pw_prg_yinchao likes this.
  8. pw_prg_yinchao

    pw_prg_yinchao

    Joined:
    Feb 14, 2020
    Posts:
    18
    Oh, that is to say, the interned string instances will not be created until I try to access them by literals or
    string.Intern()
    ?
     
  9. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,461
    No. As I understand this, literals will be part of the intern pool from whenever the code they live in gets JIT compiled or I guess statically initialized? Those that you intern explicitly will be added to the intern pool if they didn't already live there, but would have been created by you before being added there. Once interned or retrieved from there, you'll only have references to the same instance.

    If you recreate the string and get it from the interned pool, the recreated one will be a separate instance that will get collected by the GC
     
  10. pw_prg_yinchao

    pw_prg_yinchao

    Joined:
    Feb 14, 2020
    Posts:
    18
    Thank you for the explanation! And I agree with you mostly.
    But I am confused with where is the pool that contains the interned strings. Is it on the heap?
    If it is, I am wondering why they not be collected by snapshot. Otherwise, it doesn't matter anymore :)
     
  11. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,461
    afaik, they are stored together with Type Metadata and Generics in the VM Domain Heaps, which are separate from the VM GC-Managed Heaps shown in the Memory Profiler tables. Memory Map does show Domain Heaps for Mono builds, but not their content, and not yet visually distinct from empty GC Heaps as it is missing the info to distinguish between the two (2021.2 already has that info and it'll get backported but there is no version of the Memory Profiler yet available that would highlight that difference yet either).

    Good point though. We've taken a note that it might be interesting to list these out too.
     
    pw_prg_yinchao likes this.
  12. pw_prg_yinchao

    pw_prg_yinchao

    Joined:
    Feb 14, 2020
    Posts:
    18
    Thank you very much for the explanation in detail!
    So glad to hear that! Afaik, interned strings often take considerable memories and there is no good way to profile them now. So this is important information for us.