Hi there, I found jagged array (T[ ][ ]) may not be collected in memory captures.
Test codes are something like:
public class TestComponent : MonoBehaviour
{
...
private TestClass[] array1 =
{
new TestClass(),
};
private TestClass[][] array2 =
{
new [] {new TestClass(), null},
null,
};
...
}
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).
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.
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?
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
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
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.
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.