Есть приложение, которое в цикле выделяет память через 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[3]: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От:
Аноним
Дата:
20.10.08 09:00
Оценка:
Здравствуйте, -prus-, Вы писали:
P>Здравствуйте, Аноним, Вы писали:
А>>Вероятно у вас происходит фрагментация памяти. Попробуйте использовать полученые блоки памяти повторно.
P>Это сохранять старые адреса и выделать по ним?
Это значит выделеные блоки сразу не освобождать, а оставлять для повторного использования.
я так понимаю — VirtualAlloc для какихто особых случаев используется? Чем стандартный менеджер памяти не угодил?
P>А как можно дефрагментировать обратно?
под неуправляемый код — в общем случае — невозможно.
Здравствуйте, Аноним, Вы писали:
А>Это значит выделеные блоки сразу не освобождать, а оставлять для повторного использования. А>я так понимаю — VirtualAlloc для какихто особых случаев используется? Чем стандартный менеджер памяти не угодил?
HeapAlloc(GetProcessHeap(), ...) избавляет от этих проблем. Однако прога вываливается с эксепшеном Out of memory при добавлении элементов в список.
Это все для VCL-приложения... Памяти опять же процесс потребляет примерно 100 Мб....
Новую кучу создавать — это поможет?
С уважением,
Евгений
Re: VirtualAlloc и ERROR_NOT_ENOUGH_MEMORY
От:
Аноним
Дата:
20.10.08 09:32
Оценка:
P>В чем может быть причина?
Например в том что освобождающий поток не успевает свободить все то что навыделял выделяющий и память и правда закончилось. А к тому времени как вы посмотрите в ТМ сколько памяти отожрано — освобождающий все освободит и вы увидите свои "100 метров", ибо все происходит оч быстро
Здравствуйте, Аноним, Вы писали:
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.
Здравствуйте, Аноним, Вы писали:
P>>Сначала данные накапливаются в одном потоке и только по окончанию его работы об этом сообщается другому потоку. P>>На момент окончания работы первого перед освобождением памяти примерно 100 Мб А>Болбшими кусками? Allocation granularity в венде — 64кб, а размер страницы — 4 кб. 64/4 = 16. Таким образом если вы выделяете кусочками <=4kb максимум что вы навыделяете VirtualAlloc'ом — 2000MB/16 = 125mb.
Да, куски не большие — примерно 1100 байт...
Как быть?
Достаточно будет просто выделять больше 4 кб? Скажем 4100?
P>Да, куски не большие — примерно 1100 байт... P>Как быть? P>Достаточно будет просто выделять больше 4 кб? Скажем 4100?
Вы не поняли. Больше 32 тысяч кусков любого размера VirtualAlloc'ом одновременно вы не выделите. Это верхний предел количество одновременных выделений системными сервисами (VirtualAlloc/MapViewOfFile) потому что нововыделенный адрес всегда находится на выровненной по 64кб границе. Если таких границ в процессе не осталось — все — приехали. Потому в частности и существует куча.
Здравствуйте, Аноним, Вы писали:
А>Вы не поняли. Больше 32 тысяч кусков любого размера VirtualAlloc'ом одновременно вы не выделите. Это верхний предел количество одновременных выделений системными сервисами (VirtualAlloc/MapViewOfFile) потому что нововыделенный адрес всегда находится на выровненной по 64кб границе. Если таких границ в процессе не осталось — все — приехали. Потому в частности и существует куча.
Да, теперь понял... Но я поглядел и у меня < 32000. А именно 14000.
С помощью кучи данная проблема разрешается...
Здравствуйте, -prus-, Вы писали:
P>Все привет.
P>Есть приложение, которое в цикле выделяет память через VirtualAlloc и складывает указатели в список... А потом сообщяет другому потоку, что данные готовы и второй все чистит. P>Однако иногда при выделении память происходит ошибка ERROR_NOT_ENOUGH_MEMORY. P>Сам процесс потребляет примерно 100 Мб...
Выведи в лог
1) Значения указателей, возвращаемых VirtualAlloc
2) Значения указателей, освобождаемых VirtualFree
Скорее всего, станет ясно.
>На компе стоит 3 Гб ОЗУ...
Это не так важно. Здесь речь идет о виртуальной, а не физической памяти. 3 Гб виртуальной ты все равно не выделишь под x86, даже если купишь еще 3 Гб физической