2013-12-26 2 views
0

У нас есть многопоточный проект клиент-сервер, мы недавно обновили серверные приложения в 64-битной архитектуре. Решив множество проблем, наше приложение теперь неуклонно работает под большой нагрузкой. Но после этого периода приложение на сервере выходит из строя с ошибкой «Недостаточно памяти». В это время свободная память доступна в больших количествах, кажется, что проблема фрагментации памяти. Есть ли возможность дефрагментации памяти, некоторые инструменты? Или могут быть некоторые другие причины «вне памяти» в подобной ситуации? РаспределениеDelphi XE4 64-разрядная память

Память:

  1. Общий объем памяти: 96 ГБ
  2. Physical: 48GB
  3. Virtual: 48GB
  4. Количество свободной физической памяти в момент распада: 3GB
  5. Объем свободной виртуальной памяти во время краха: 45Gb
  6. Максимальный объем памяти, выделяемый на поток: 1GB
+0

Возможно, вы можете найти или сконструировать диспетчер памяти, менее уязвимый для фрагментации в вашем конкретном сценарии. Для примера, что, если каждый поток будет иметь свой собственный пул кучи, чтобы все было свободным, когда поток заканчивается? –

ответ

4

Как вы догадались, ваша проблема - фрагментация. Нет ничего, что можно сделать для дефрагментации памяти - любой инструмент, который попытается сделать это, должен иметь полную карту каждого указателя в вашей программе. Обратите внимание, что даже сборщик мусора .NET не может выполнить это с большой кучей объектов, я разбил 32-битное сетевое приложение, использующее только 100 МБ.

Вместо этого вам необходимо избегать фрагментации в первую очередь. Обычно это означает пулы объектов, сохраняя старые объекты для повторного использования, а не освобождая их, а затем перераспределяя их.

+0

Спасибо. Можно ли привести ссылки на примеры реализации пула объектов? – Sibay

+0

Забыл сказать, что мы использовали COM-объекты, это также верно для них? – Sibay

+0

какой язык/RTL эти COM-объекты написаны? –

3

Другой вариант (если услуга не критична по времени и должна быть онлайн 100% каждой секунды), необходимо перезапустить службу каждые 24 часа или около того (либо через планировщик задач, либо из вашей собственной программы).

Если в вашей собственной программе вы можете сделать это одним из двух способов, в зависимости от того, какой тип обслуживания у вас есть (если могут существовать два экземпляра вашего сервиса в то же самое - краткое время):

1) Execute a second instance of your service from within your currently running service and then terminate 
2) Execute a tiny helper program that waits f.ex. 5 seconds and then (re)starts your service, then terminate your currently running service 

Но лучшим способом было бы избежать фрагментации в первую очередь, как пишет Лорен Пехтель.

+0

Спасибо, мы используем его сейчас :) – Sibay

+0

Не забудьте принять ответ, затем (нажмите галочку) – HeartWare

Смежные вопросы