Search Unity

I have a gc alloc almost every frame by NetworkIdentity.UNetStaticUpdate()

Discussion in 'UNet' started by XuTenTen, Sep 2, 2016.

  1. XuTenTen

    XuTenTen

    Joined:
    Apr 30, 2015
    Posts:
    14
    I have a gc alloc almost every frame by NetworkIdentity.UNetStaticUpdate()

    I'm using MessageBase define as
    public class MsgSyncTrans : MessageBase
    {
    public uint netId;
    public Vector3 pos;
    public bool facing;
    public float timeStamp;
    }
    it will be send every frame.

    the profile show gc alloc as in picture.

    How can I avoid that gc alloc?
     

    Attached Files:

    • GC.png
      GC.png
      File size:
      53.1 KB
      Views:
      895
  2. BonyYousuf

    BonyYousuf

    Joined:
    Aug 22, 2013
    Posts:
    110
    I'm having the same issue. Unity should optimize their unet code for better memory allocation
     
  3. donnysobonny

    donnysobonny

    Joined:
    Jan 24, 2013
    Posts:
    220
    Okay so two things:

    big BIG no-no. One of the most common rookie mistakes is to think that in order to synchronize the position (for example) of objects over the network we must send the data every frame, or at least fast enough so that it looks "smooth". You don't want to be doing this. Bandwidth is one of the most scarce resources when you look at it's availability across devices and globally so you need to use it very sparingly. Multiplayer/network programming mostly consists of looking at what needs to happen over the network (for example, synchronizing position/rotation) and how to do this as infrequently as possible while sending the smallest amount of data possible.

    A general rule with position/rotation synchronization is to send updates somewhere between 2 to 10 times per second and on the client-side, use interpolation to "smooth" the gaps between updates. For example, check out Vector3.Lerp, which allows you to smooth the values within a Vector3 between two Vector3s over time.

    Secondly, the entries in the image that you have shown are almost certainly not related to the MessageBase instance that you are referring to in your post. However, to help you get to the bottom of it, here's some tips:
    • you should see a significant drop in your garbage generation when you optimize your networking (ie: send your position updates far less frequently)
    • if you are worried about GC, which you don't primarily need to be, then don't use MessageBase instances. MessageBase instances, like a lot of the HLAPI are a convenience feature. They merely make your life easier at the cost of things like cpu, ram and garbage. Check out the SendWriter methods within the NetworkClient/NetworkConnection classes. These allow you to bypass the MessageBase step by passing in a NetworkWriter instance (which is ultimately what a MessageBase ends up doing)
    • The reason why the above will help with GC is because every construction of an object creates garbage (because of how objects and large pieces of data are stored in memory). So any time you see the "new" keyword, or unity uses the "new" keyword internally (which it will be for your MessageBase), that generates garbage
    • Strings are referenced types in c#. This means they function very similarly to objects in c#. When you do something like string str = "something"; or str += "something"; or string str = 123.ToString(); or anything else that is effectively assigning a string value to memory, you are generating garbage. We get told to use StringBuilders to solve this issue, but that only partially helps. The best thing to do is avoid assigning strings to memory as much as you can.
    • The reason I mention the above, is somewhere in your code you are regularly calling ToString() on a short (int16), either intentionally or unintentionally, within your networking. Assigning strings to memory regularly is one of the easiest ways to generate huge amounts of garbage.
    Hopefully this helps. Good luck!
     
    TwoTen likes this.