Search Unity

Am I going crazy? Big memory leak in NetworkTransport.Send()?

Discussion in 'Multiplayer' started by NongBenz, Jun 24, 2017.

  1. NongBenz

    NongBenz

    Joined:
    Sep 30, 2014
    Posts:
    26
    I've spent weeks looking through my code for a big memory leak that's been crashing game servers. And I've pulled out all of my code and was left with this... NetworkTransport.Send()!! one of the most commonly used functions in the game is eating memory roughly at the same rate that data is sent... which leads me to think that maybe the sent data isn't being released.

    Maybe I'm worng, so please let me know if this code leaks for you as well. I'm really just frustrated at the time wasted if one of the most important functions wasn't smoke tested. Thanks.

    Code (csharp):
    1.  
    2. public class test : MonoBehaviour {
    3.  
    4.     int m_MyHostId;
    5.     int m_PeerId;
    6.     byte error;
    7.  
    8.     bool connected = false;
    9.  
    10.     void Start()
    11.     {
    12.         NetworkTransport.Init ();
    13.         ConnectionConfig myConfig = new ConnectionConfig();
    14.         myConfig.AddChannel(QosType.Reliable);
    15.  
    16.         HostTopology myTopology = new HostTopology(myConfig, 10);         //up to 10 connection allowed
    17.         m_MyHostId = NetworkTransport.AddHost(myTopology, 9999);
    18.  
    19.         m_PeerId = NetworkTransport.Connect(m_MyHostId, "127.0.0.1", 9999, 0, out error);
    20.         if ((NetworkError)error != NetworkError.Ok)
    21.         {
    22.             Debug.LogError("Network error is occurred: " + (NetworkError)error);
    23.         }
    24.     }
    25.  
    26.     void Update()
    27.     {
    28.         int recHostId;
    29.         int connectionId;
    30.         int channelId;
    31.         byte[] recBuffer = new byte[1024];
    32.         int bufferSize = 1024;
    33.         int dataSize;
    34.  
    35.         if (connected) {
    36.             for (int i = 0; i < 2; i++) {
    37.                 NetworkTransport.Send (m_MyHostId, m_PeerId, 0, new byte[500], 500, out error);
    38.  
    39.                 if ((NetworkError)error != NetworkError.Ok)
    40.                 {
    41.                     Debug.LogError("Network error is occurred: " + (NetworkError)error);
    42.                 }
    43.             }
    44.         }
    45.  
    46.         while (true) {
    47.             NetworkEventType recData = NetworkTransport.Receive (out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
    48.  
    49.             if ((NetworkError)error != NetworkError.Ok) {
    50.                 Debug.LogError ("Network error is occurred: " + (NetworkError)error);
    51.                 break;
    52.             }
    53.  
    54.             if (recData == NetworkEventType.Nothing) {
    55.                 break;
    56.             }
    57.  
    58.             switch (recData) {
    59.             case NetworkEventType.ConnectEvent:
    60.                 Debug.Assert (connectionId == m_PeerId, "Success");
    61.                 connected = true;
    62.                 break;
    63.             case NetworkEventType.DataEvent:
    64.                 Debug.Log ("Received Data");
    65.                 break;
    66.             case NetworkEventType.DisconnectEvent:
    67.                 Debug.Assert (connectionId == m_PeerId, "Failure");
    68.                 connected = false;
    69.                 break;
    70.             default:
    71.                 break;
    72.             }
    73.         }
    74.     }
    75. }
    76.  
     
    KyleOlsen likes this.
  2. JonRurka

    JonRurka

    Joined:
    Nov 19, 2012
    Posts:
    35
    Just a guess, but instead of sending in "new byte[500]" for the buffer, try defining a global SendBuffer array, allocate it in Start() to 500, and send that into the Send function. Every time it's allocating a completely new 500 byte long array in memory, and having it's pointer sent to the C++ code (which may or may not release and de-allocate it). When you send a reference to a global array variable, you are sending the same memory address(s) every time for it to use, It will not matter if the C++ code releases the memory because it will only ever use those 500 memory addresses every single Send call.
     
    Last edited: Jun 24, 2017
  3. NongBenz

    NongBenz

    Joined:
    Sep 30, 2014
    Posts:
    26
    Just tried and still increasing at the same rate... I've even put in a System.GC.Collect() to make sure it wasn't the garbage collection fooling around.

    Hope we can get a fix for this as soon as possible, since my game is live now and servers are chewing through memory left and right. With 64 players online at 1-2MB server upload speeds it doesnt take long.
     
    KyleOlsen likes this.
  4. KyleOlsen

    KyleOlsen

    Joined:
    Apr 3, 2012
    Posts:
    237
    If you post your bug report # here it will have a higher chance of getting looked at soon.
     
  5. NongBenz

    NongBenz

    Joined:
    Sep 30, 2014
    Posts:
    26
    KyleOlsen likes this.
  6. NongBenz

    NongBenz

    Joined:
    Sep 30, 2014
    Posts:
    26
    Ok I did some more testing. Had to go back to v5.6.1 without the leak... then I tested v5.6.1p2 it has the problem and everything after that too. So it could be patch 1 or 2 where it started. Hope this will help @aabramychev solve the issue.
     
    KyleOlsen likes this.
  7. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    If Alex looks into this it will be great. However, next to this thread, you should really create an official bug report ticket for this as well. This assures that unity QA looks into this.
     
    NongBenz likes this.
  8. aabramychev

    aabramychev

    Unity Technologies

    Joined:
    Jul 17, 2012
    Posts:
    574
    Sorry for no response guys... was busy. Will take a look today and will report about result here
     
    KyleOlsen likes this.
  9. NongBenz

    NongBenz

    Joined:
    Sep 30, 2014
    Posts:
    26
    Thank you Alex! The leak starts slow... seems related to the size of the Send/RecieveQueue. But once some internal buffer is filled up I guess, the memory leak grows faster.
     
  10. KyleOlsen

    KyleOlsen

    Joined:
    Apr 3, 2012
    Posts:
    237
    NongBenz likes this.
  11. Mariusj

    Mariusj

    Unity Technologies

    Joined:
    Oct 27, 2016
    Posts:
    8
    Hey there!

    I wanted to inform that this problem should be fixed in 5.6.2p2.

    If this problem is still present, make sure to inform us in this forum thread or by submitting a new case.
     
    NongBenz and HiddenMonk like this.
  12. KyleOlsen

    KyleOlsen

    Joined:
    Apr 3, 2012
    Posts:
    237
    Any news on when it'll make it into 2017?
     
  13. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    +1, would like to know too
     
  14. Fijit

    Fijit

    Joined:
    Sep 1, 2011
    Posts:
    7
    In case you've not seen it yet it looks like 2017.1.0f3 for the fix, so I imagine sometime next week..

    This from the known issues list for 2017.1.0f2
    • Multiplayer: NetworkTransport.Send() leaks memory (fixed in f3) (923903)
     
    KyleOlsen, NongBenz and xVergilx like this.
  15. alexr1221

    alexr1221

    Joined:
    Mar 5, 2016
    Posts:
    70
    Last edited: Sep 4, 2018