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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

WinRTBridge.GCHandledObjects.FreeHandles

Discussion in 'Windows' started by fallFlat, Mar 14, 2015.

  1. fallFlat

    fallFlat

    Joined:
    Mar 26, 2014
    Posts:
    26
    Could anyone from Unity explain scalability of WinRTBridge.GCHandledObjects.FreeHandles method in Unity 4.6?

    We have a problem that performance of our game degrades over time (reloading level multiple times). I've spent quite some time profiling it and discovered that time spent in this method increases dramatically.
    Early game - FreeHandles takes 10.98% of all CPU, after playing for some time grows to 37.07%. If is mostly influenced by COMInterlocked::CompareExchange which grows from 8.93% to 30.51%.

    The worst thing that GC happens due to issues out of our control:
    * physics, keeps allocating ContactInfo,
    * Audio manager on WP8 seems to reallocate new buffer for each call of OnAudioFilterRead,
    * UI is keen on allocating huge amounts of UIVertex [] of same size each frame (mostly in Text component).
    Unity profiler shows none of those allocations, but Visual Studio profiler exposes it.
    So in the end we can get 1-2 GC per second!

    If I knew some of inner workings of FreeHandles algorithm I could check if I'm doing something wrong in our code. What is the working set of objects it operates on, how do they get there, when they are removed from working set?

    Overall memory usage in our game is quite stable, so it is should not be caused by leaked C# objects, meshes or components.

    Best Regards
    Tomas
     
  2. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,672
    The method frees objects which are created from native->managed, or managed->native transitions, basically it checks if something is referencing the managed object in the native land (Unity runtime code), if not - the object is "freed"

    So whenever you call into UnityEngine API, you create a managed object which is used in native land, in most cases -object is freed instantly, because nothing is referencing it in native land.

    The less transitions native->managed, managed->native - there are, the less pressure there is on FreeHandles.

    Hope that helps a bit.

    P.S Just to be sure, you're using Master config, right? Also try running your game without Visual Studio debugger attached, and it also affects performance.
     
    Last edited: Mar 14, 2015
  3. fallFlat

    fallFlat

    Joined:
    Mar 26, 2014
    Posts:
    26
    Yes master config, no debugger when running the game and frame drops appear after reloading levels couple of times down to a point when game is no longer playable.

    We generate level geometry procedurally - no LoadLevel, single scene project. At load time there will be a lot managed/unmanaged transitions to upload all the meshes, generate components, etc. All these objects are destroyed.

    Profiling is done using CPU sampling from Visual Studio Phone Performance Analyser: Types.png

    Leaked things are:
    ContactPoint allocated in UnityEngine.DLL (the ones from WinRTBridge are collected).
    Methods.png
    References are being held by GCHandledObjects.

    The other two leaked things are Int32[] x2, Object[] x1 and finally WinRTBridge.GCHandledObjects+Block. Which are allocated when we call AnimationCurve.Evaluate.

    I guess this explains the slow down behavior - some leaks from AnimationCurve.Evaluate and ContactPoints keep growing GCHandledObjects.Block and your collector had to process all of these refs.

    I can get away without using animationcurves - it's for audio mixing only, but ContactPoints is needed for physics. I'm accessing contact points with foreach loop, in OnCollisionEnter/Stay. I do not store references to ContactPoints outside of foreach.

    Any ideas?
     

    Attached Files:

  4. fallFlat

    fallFlat

    Joined:
    Mar 26, 2014
    Posts:
    26
    Just to confirm - commenting out access to AnimationCurve.Evaluate and OnCollisionEnter/OnCollisionStay methods prevents leaks and performance degradation. Even empty OnCollisionEnter/OnCollisionStay methods are causing the leak and slowdown.

    Problem is - these handlers are needed (would not be there otherwise). Should I submit a bug report?
     
  5. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,672
    I am bit confused, in your first post you said "Overall memory usage in our game is quite stable,", but now you're saying that there's really a leak.

    Without a repro project, it's really hard to say, but yes, you're right if objects are leaking, the array in GCHandledObjects keeps growing, that way causing performance penalty as well.

    Please sumbit a bug, with small repro project if possible.
     
  6. fallFlat

    fallFlat

    Joined:
    Mar 26, 2014
    Posts:
    26
    "Quite stable" means that there is no big variation between level reloads. We generate the world procedurally and use custom pooling for CLR objects extensively - overall memory usage from our code varies between loads, but converges eventually.

    I've submitted repro project, along with VS performance report.
     
  7. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,672
    By the way, did you try to check it, if the issue is in 5.0 as well?
     
  8. fallFlat

    fallFlat

    Joined:
    Mar 26, 2014
    Posts:
    26
    No, not yet.
     
  9. fallFlat

    fallFlat

    Joined:
    Mar 26, 2014
    Posts:
    26
    Just check in Unity5, no leaks with the repro project. We are migrating to Unity5 this week, I hope it will all be fine in Unity 5.
     
  10. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,672
    Found the leak, sadly it's available in 5.0 as well, it's not reproducible there because ContactPoints are created in a different way... Anyways, this is a big bug, thanks for finding this, we'll apply a fix in both 4.6 and 5.0.
     
  11. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,672
    Just an update, it should end up in 4.6.3 Patch 4 and 5.0.0 patch 2
     
  12. fallFlat

    fallFlat

    Joined:
    Mar 26, 2014
    Posts:
    26
    Thanks, looking forward.