VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: -prus-  
Дата: 20.10.08 08:15
Оценка:
Все привет.

Есть приложение, которое в цикле выделяет память через VirtualAlloc и складывает указатели в список... А потом сообщяет другому потоку, что данные готовы и второй все чистит.
Однако иногда при выделении память происходит ошибка ERROR_NOT_ENOUGH_MEMORY.
Сам процесс потребляет примерно 100 Мб... На компе стоит 3 Гб ОЗУ...

В чем может быть причина?

Заранее благодарен!
С уважением,
Евгений
Re: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: Аноним  
Дата: 20.10.08 08:22
Оценка:
Здравствуйте, -prus-, Вы писали:

P>Все привет.


P>Есть приложение, которое в цикле выделяет память через VirtualAlloc и складывает указатели в список... А потом сообщяет другому потоку, что данные готовы и второй все чистит.

P>Однако иногда при выделении память происходит ошибка ERROR_NOT_ENOUGH_MEMORY.
P>Сам процесс потребляет примерно 100 Мб... На компе стоит 3 Гб ОЗУ...

P>В чем может быть причина?


P>Заранее благодарен!


Вероятно у вас происходит фрагментация памяти. Попробуйте использовать полученые блоки памяти повторно.
Re[2]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: -prus-  
Дата: 20.10.08 08:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вероятно у вас происходит фрагментация памяти. Попробуйте использовать полученые блоки памяти повторно.


Это сохранять старые адреса и выделать по ним?
А как можно дефрагментировать обратно?
С уважением,
Евгений
Re[3]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: Аноним  
Дата: 20.10.08 09:00
Оценка:
Здравствуйте, -prus-, Вы писали:

P>Здравствуйте, Аноним, Вы писали:


А>>Вероятно у вас происходит фрагментация памяти. Попробуйте использовать полученые блоки памяти повторно.


P>Это сохранять старые адреса и выделать по ним?

Это значит выделеные блоки сразу не освобождать, а оставлять для повторного использования.
я так понимаю — VirtualAlloc для какихто особых случаев используется? Чем стандартный менеджер памяти не угодил?

P>А как можно дефрагментировать обратно?

под неуправляемый код — в общем случае — невозможно.
Re[4]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: -prus-  
Дата: 20.10.08 09:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Это значит выделеные блоки сразу не освобождать, а оставлять для повторного использования.

А>я так понимаю — VirtualAlloc для какихто особых случаев используется? Чем стандартный менеджер памяти не угодил?

HeapAlloc(GetProcessHeap(), ...) избавляет от этих проблем. Однако прога вываливается с эксепшеном Out of memory при добавлении элементов в список.
Это все для VCL-приложения... Памяти опять же процесс потребляет примерно 100 Мб....
Новую кучу создавать — это поможет?
С уважением,
Евгений
Re: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: Аноним  
Дата: 20.10.08 09:32
Оценка:
P>В чем может быть причина?
Например в том что освобождающий поток не успевает свободить все то что навыделял выделяющий и память и правда закончилось. А к тому времени как вы посмотрите в ТМ сколько памяти отожрано — освобождающий все освободит и вы увидите свои "100 метров", ибо все происходит оч быстро
Re[2]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: -prus-  
Дата: 20.10.08 09:59
Оценка:
Здравствуйте, Аноним, Вы писали:

P>>В чем может быть причина?

А>Например в том что освобождающий поток не успевает свободить все то что навыделял выделяющий и память и правда закончилось. А к тому времени как вы посмотрите в ТМ сколько памяти отожрано — освобождающий все освободит и вы увидите свои "100 метров", ибо все происходит оч быстро

Сначала данные накапливаются в одном потоке и только по окончанию его работы об этом сообщается другому потоку.
На момент окончания работы первого перед освобождением памяти примерно 100 Мб
С уважением,
Евгений
Re[3]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: Аноним  
Дата: 20.10.08 10:17
Оценка:
P>Сначала данные накапливаются в одном потоке и только по окончанию его работы об этом сообщается другому потоку.
P>На момент окончания работы первого перед освобождением памяти примерно 100 Мб
Болбшими кусками? Allocation granularity в венде — 64кб, а размер страницы — 4 кб. 64/4 = 16. Таким образом если вы выделяете кусочками <=4kb максимум что вы навыделяете VirtualAlloc'ом — 2000MB/16 = 125mb.
Re[4]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: -prus-  
Дата: 20.10.08 10:36
Оценка:
Здравствуйте, Аноним, Вы писали:

P>>Сначала данные накапливаются в одном потоке и только по окончанию его работы об этом сообщается другому потоку.

P>>На момент окончания работы первого перед освобождением памяти примерно 100 Мб
А>Болбшими кусками? Allocation granularity в венде — 64кб, а размер страницы — 4 кб. 64/4 = 16. Таким образом если вы выделяете кусочками <=4kb максимум что вы навыделяете VirtualAlloc'ом — 2000MB/16 = 125mb.

Да, куски не большие — примерно 1100 байт...
Как быть?
Достаточно будет просто выделять больше 4 кб? Скажем 4100?
С уважением,
Евгений
Re[5]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: Аноним  
Дата: 20.10.08 10:40
Оценка: 3 (2)
P>Да, куски не большие — примерно 1100 байт...
P>Как быть?
P>Достаточно будет просто выделять больше 4 кб? Скажем 4100?
Вы не поняли. Больше 32 тысяч кусков любого размера VirtualAlloc'ом одновременно вы не выделите. Это верхний предел количество одновременных выделений системными сервисами (VirtualAlloc/MapViewOfFile) потому что нововыделенный адрес всегда находится на выровненной по 64кб границе. Если таких границ в процессе не осталось — все — приехали. Потому в частности и существует куча.
Re[6]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: -prus-  
Дата: 20.10.08 11:23
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вы не поняли. Больше 32 тысяч кусков любого размера VirtualAlloc'ом одновременно вы не выделите. Это верхний предел количество одновременных выделений системными сервисами (VirtualAlloc/MapViewOfFile) потому что нововыделенный адрес всегда находится на выровненной по 64кб границе. Если таких границ в процессе не осталось — все — приехали. Потому в частности и существует куча.


Да, теперь понял... Но я поглядел и у меня < 32000. А именно 14000.
С помощью кучи данная проблема разрешается...
С уважением,
Евгений
Re[6]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: -prus-  
Дата: 20.10.08 11:25
Оценка:
Здравствуйте, Аноним, Вы писали:

---

Прошу прощения... У меня примерно 17000 кусков и списка 2, следовательно вы правы...
+2
С уважением,
Евгений
Re: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: Pavel Dvorkin Россия  
Дата: 20.10.08 11:48
Оценка:
Здравствуйте, -prus-, Вы писали:

P>Все привет.


P>Есть приложение, которое в цикле выделяет память через VirtualAlloc и складывает указатели в список... А потом сообщяет другому потоку, что данные готовы и второй все чистит.

P>Однако иногда при выделении память происходит ошибка ERROR_NOT_ENOUGH_MEMORY.
P>Сам процесс потребляет примерно 100 Мб...

Выведи в лог
1) Значения указателей, возвращаемых VirtualAlloc
2) Значения указателей, освобождаемых VirtualFree

Скорее всего, станет ясно.

>На компе стоит 3 Гб ОЗУ...


Это не так важно. Здесь речь идет о виртуальной, а не физической памяти. 3 Гб виртуальной ты все равно не выделишь под x86, даже если купишь еще 3 Гб физической
With best regards
Pavel Dvorkin
Re: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: K_Os  
Дата: 20.10.08 12:05
Оценка:
Нужно выделить один большой буфер, самостоятельно сгенерировать указатели на разные места в этом буфере.

BYTE *buffer = (BYTE*)VirtualAlloc(NULL, buffer_size, MEM_COMMIT, PAGE_READWRITE);
BYTE **objects = new BYTE*[number_object];

for(int i=0; i<number_object; i++)
{
objects[i]=buffer+object_size*i;
}
Re[5]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От: Leonid Troyanovsky  
Дата: 20.10.08 15:47
Оценка:
Здравствуйте, -prus-, Вы писали:

P>Это все для VCL-приложения... Памяти опять же процесс потребляет примерно 100 Мб....


GetMem/FreeMem
--
С уважением, LVT
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.