Лучше ли каждый раз выделять / освобождать IntPtr (AllocHGlobal) или сохранять его? - PullRequest
1 голос
/ 05 января 2011

У меня есть ситуация, когда я использую AllocHGlobal (всегда одинакового размера) для функции, которую я часто использую (вероятно, 30 раз в секунду), в конце функции, которую я вызываю FreeHGlobal

Isлучше, если я сохраню часть памяти, выделенную с помощью AllocHGlobal, и освобожу ее, когда класс Dispose, или я должен распределять / освобождать каждый раз, когда вызываю функцию?

Я не знаю, как эта память ведет себя в c #,«новый мир» для меня

Ответы [ 3 ]

2 голосов
/ 05 января 2011

30 секунд - это вечность. Гораздо проще поместить FreeHGlobal в последний блок, чтобы обеспечить его выпуск. Спасает вас от необходимости делать финализатор и IDisposable песни и танцы. Ну, код клиента.

Избавление от кэширования в куче не начинает окупаться, пока не достигнет миллисекундного диапазона.

1 голос
/ 05 января 2011

Как и в случае любого вопроса производительности - сначала напишите чистый код, измерьте и оптимизируйте то, что нужно.

Если вы уверены, что ваш объект никогда не будет использоваться несколькими потоками (таким образом, делая одновременные вызовырассматриваемая функция) вроде бы нормально кешировать выделенную память.

Если вы решите кешировать неуправляемый блок памяти, полагаясь на сборку мусора, то, скорее всего, будет недостаточно, чтобы освободить память достаточно рано.Неуправляемая память (AllocHGlobal) не засчитывается в выделенную память CLR, что потенциально задерживает сбор мусора ваших объектов).Вы должны внедрить и правильно использовать IDisposable на ваших объектах.

0 голосов
/ 05 января 2011

Вы можете сделать это, если:

  • Объем требуемой памяти всегда меньше или равен размеру вашего выделения.(Вы уже указали, что это так.)
  • Метод вызывается не более чем из одного потока за раз.
  • Метод не является входящим.
  • Вы осторожны, чтобы освободить память, когда она больше не нужна.(Другими словами, если указатель сохраняется на нестатическом поле класса, класс должен реализовать IDisposable, а метод Dispose() должен освободить память. И, конечно, потребители класса должны будут вызвать Dispose() или используйте блок using(){}.)

Однако гораздо более вероятно, что фактическое маршалинг вызова P / Invoke станет узким местом.Вы на самом деле уже профилировали код, или вы микрооптимизируете?

...