Почему мой простой клиент Lidgren использует так много памяти? - PullRequest
3 голосов
/ 06 сентября 2011

У меня есть простой клиент и сервер, который использует lidgren.Клиент постоянно отправляет запросы на сервер (сообщения, состоящие из одного байта со значением 1), а клиент отвечает «данными» (2000 ushorts).Он делает это примерно 20 раз в секунду.Я сохраняю входящие данные в списке, который я очищаю при каждом получении данных.Проблема в том, что я наблюдаю за использованием памяти для client.exe в диспетчере задач, и он просто идет вверх и вверх.Это поднялось до 100 МБ за десять минут.Иногда я могу побудить сборщик мусора к запуску, но он, похоже, лишь немного экономит использование памяти.

Вот код моего сервера:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lidgren.Network;
using System.Threading;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            NetPeerConfiguration config = new NetPeerConfiguration("testapp");
            config.UseMessageRecycling = true;
            config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
            NetClient netClient = new NetClient(config);
            netClient.Start();
            netClient.DiscoverLocalPeers(12313);

            List<ushort> mylist = new List<ushort>();
            NetIncomingMessage msg;

            while (true)
            {
                if (Console.KeyAvailable && Console.ReadKey().Key == ConsoleKey.G)
                {
                    GC.Collect();
                }

                while ((msg = netClient.ReadMessage()) != null)
                {
                    switch (msg.MessageType)
                    {
                        case NetIncomingMessageType.DiscoveryResponse:
                            netClient.Connect(msg.SenderEndpoint);
                            Thread.Sleep(1000);

                            //request data from server
                            NetOutgoingMessage nom = netClient.CreateMessage();
                            nom.Write((byte)1);
                            netClient.SendMessage(nom, NetDeliveryMethod.ReliableUnordered);
                            break;
                        case NetIncomingMessageType.Data:
                            mylist.Clear();
                            for (ushort n = 0; n < 2000; n++) mylist.Add(msg.ReadUInt16());

                            //request more data
                            NetOutgoingMessage nom2 = netClient.CreateMessage();
                            nom2.Write((byte)1);
                            netClient.SendMessage(nom2, NetDeliveryMethod.ReliableUnordered);

                            break;
                        default:
                            break;
                    }
                    netClient.Recycle(msg);
                }

            }

        }

    }
}

и воткод для моего клиента:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lidgren.Network;
using System.Threading;

namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            NetServer server = null;

            NetPeerConfiguration config = new NetPeerConfiguration("testapp");
            config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
            config.Port = 12313;
            server = new NetServer(config);
            server.Start();

            NetIncomingMessage msg;
            while (true)
            {
                while ((msg = server.ReadMessage()) != null)
                {
                    switch (msg.MessageType)
                    {
                        case NetIncomingMessageType.DiscoveryRequest:
                            Console.WriteLine("Discovery");
                            server.SendDiscoveryResponse(null, msg.SenderEndpoint);
                            break;
                        case NetIncomingMessageType.Data:
                            byte mtype = msg.ReadByte();
                            if (mtype == 1)
                            {
                                //user is requesting an update.
                                NetOutgoingMessage nom = server.CreateMessage();
                                for (ushort n = 0; n < 2000; n++) nom.Write(n);

                                server.SendMessage(nom, msg.SenderConnection, NetDeliveryMethod.ReliableUnordered);
                            }

                            Thread.Sleep(50);

                            break;
                        default:
                            break;
                    }

                    server.Recycle(msg);
                }
            }
        }
    }
}

Я пытался использовать .NET Memory Profiler и, насколько я могу убедиться, libgren где-то удерживает мои входящие данные, хотя я не совсем понимаю внутренности.Я думаю, что слишком много данных отправляется слишком быстро и помещается в очередь где-то на клиенте.Это случается?Использование памяти сервером стабильно.

1 Ответ

3 голосов
/ 07 сентября 2011

В итоге я получил ответ от Лидгрена на сайте проекта (сначала я должен был опубликовать проблему там, но меня смутили различные страницы Лидгрена в коде Google и я подумал, что проект мертв)Это было признано проблемой в Лидгрене, и сегодня стало доступно исправление http://code.google.com/p/lidgren-network-gen3/issues/detail?id=65#makechanges.

...