The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Контроль объема используемой памяти на Си"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"Контроль объема используемой памяти на Си"  
Сообщение от Virius email on 23-Дек-08, 12:04 
Всегда были проблемы при работе с памятью, и сейчас возник следующий вопрос. У меня в программе на Си в Linux'е используется динамический список. Соответственно есть два потока: один добавляет в список записи, другой их обрабатывает и удаляет. Для выделения/очистки памяти используется *alloc/free. Добавление происходит быстрей удаления, что естественно ведет к постоянному росту списка, что в конечном счете может привести к переполнению памяти. Соответственно вопрос, как этого избежать? Можно ли, например, задать программе (внутри самой программы) какое-то ограничение на объем доступной памяти, и при этом, соответственно, определить момент, когда этот предел будет достигнут (в этом случае можно было бы делать паузу и ждать, пока снова не появится достаточно доступной памяти)? Просто подсчитывать количество выделенной памяти ведь не подойдет, так как выделяемые и освобождаемые участки памяти всегда разной длины, что ведет к дефрагментации и в конечном счете доступно будет гораздо меньше памяти, чем действительно свободно.

Кроме того, я пытался использовать процессы вместо потоков и разделяемую память, но в этом случае ограничение на объем доступной разделяемой памяти оказался слишком маленький (не то 32Мб, не то 64). Может кто-нибудь знает, как увеличить это ограничение хотя бы до 2Гб?

И забыл сказать. Программа написана под Red Hat Enterprise Linux 3.0 (ядро linux 2.4.21)

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Контроль объема используемой памяти на Си"  
Сообщение от Andrey Mitrofanov on 23-Дек-08, 13:18 
>Добавление происходит быстрей удаления, что естественно ведет к постоянному росту
> к переполнению памяти. Соответственно вопрос, как этого избежать?

Неужели удалять быстрее, чем добавляешь??

Может быть, подумать, кой чорт понёс^W^W^Wзачем тебе понадобились потоки/форки? Сделать _выводы_.

Например, читать-писать _последовательно_ в __одном__ потоке. Или исхитриться и читать двумя или более потоками, коли уж один "не успевает" (это не избавляет от необходимости синхронизации/блокировки ресурсов или какого ни IPC; и разнесения читателей по разным cpu). Оптимизировать производительность читателя, чтоб успевал. Купить сервер, чтоб успевал. Купить много серверов, чтоб успевали. Ещё ускорять читателя - отложить часть работы, например, "синхронно" писать на диск, потом медленно/асинхронно оборабатывать. Диск он большой -- авось поместится.

100рублейвкассублин!

2Maxim Chirkov: Гы, куда страждущим переводить _деньги_ за консультацию? Заведи кошелёк opennet что ли?.. %-)) И доп.поле "[_  ] руб. в кассу!", и ключь-идентификатор для вписывания в квиток %) перевода, и "лампочку" [ОПЛАЧЕНО] на ответах. :D Желаю анонимно зарабатывать денег уважаемому сайту и немеряной, но оцененной Славы. Как бы ещё анонимных неплательщиком пиночить? %)

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

Феерично.......

>Может кто-нибудь знает, как увеличить это ограничение хотя бы до 2Гб?

Вам, может быть, нужен програмист?

>И забыл сказать. Программа написана под Red Hat Enterprise Linux 3.0 (ядро linux 2.4.21)

Не-е-е, в интырпрайз программировании тут никто ничего не понимает... Это Вам на бизнес-кусы надо.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Контроль объема используемой памяти на Си"  
Сообщение от Virius email on 23-Дек-08, 14:05 
Видимо моя ошибка, что не описал задачу подробней. Хотя и причин для смеха в своем текте я не нахожу.

>Неужели удалять быстрее, чем добавляешь??
>
>Может быть, подумать, кой чорт понёс^W^W^Wзачем тебе понадобились потоки/форки? Сделать _выводы_.
>

Удаляю я как раз медленней, о чем и написал. Потому что первый поток только добавляет, а второй еще и обработкой занимается с записью обработанных данных в БД. Из-за работы с БД основные тормаза и идут. Поэтому и используется конвеер, чтобы успевать принимать данные. И в данный момент используются процессы (форки) с промежуточным буфером в разделяемой памяти. И тут-то встала проблема, что в разделяемой памяти буфер может быть не больше 32/64Мб. Как увеличить этот предел - мне не известно. Хочу перевести это дело на потоки, так как с потоками все данные находятся в одном адресном пространстве, но встает проблема с тем, как контралировать заполнение памяти так, чтобы не прейти к переполнению.

>Например, читать-писать _последовательно_ в __одном__ потоке. Или исхитриться и читать двумя или
>более потоками, коли уж один "не успевает" (это не избавляет от
>необходимости синхронизации/блокировки ресурсов или какого ни IPC; и разнесения читателей по
>разным cpu). Оптимизировать производительность читателя, чтоб успевал. Купить сервер, чтоб успевал.
>Купить много серверов, чтоб успевали. Ещё ускорять читателя - отложить часть
>работы, например, "синхронно" писать на диск, потом медленно/асинхронно оборабатывать. Диск он
>большой -- авось поместится.
>

Двумя и более потоками читать не получится. Слишком муторно и труднореализуемо, если вообще реализуемо. Мощность сервера и без того достаточная. Вся загвоздка в том, что данные приходят быстрей, чем программа, успевает их записать в БД. Тут все утыкается в производительность дискового массива, который используется для хранения БД, но его заменить щас не возможно. Да и замена его на более быстрый думаю не сильно бы помогла. Поэтому все опять же возвращается к означенным мной ранее вопросом, на которые я надеюсь кто-нибудь таки сможет мне ответить.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Контроль объема используемой памяти на Си"  
Сообщение от pavel_simple (??) on 24-Дек-08, 07:32 
1. менять дизайн проги по любому -- т.к. передача данных от процесса к процессу не есть верный способ.
2. у современных БД есть асинхронные вызовы
3. если БД не успевает это записывать из-за диска это одно, если из-за того что не оптимизированы запросы/таблицы это другое
4. если БД оптимизировать нельзя, и запись не успевает нужно менять железо как не подходящее для задачи.


всё это напоминает решение задачи "считаем трафик", только через Ж

что хоть прога делает? -- частенько встречаются случаи с неверной постановкой задачи и соответствующей реализацией


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Контроль объема используемой памяти на Си"  
Сообщение от vic (??) on 23-Дек-08, 22:54 
>Всегда были проблемы при работе с памятью, и сейчас возник следующий вопрос.

Изучайте матчасть и закрывайте пробелы.

>У меня в программе на Си в Linux'е используется динамический список.

переходите на с++ что ли, уже 2009 год на дворе и  эта ваша фраза как-то пугает, видимо наследуемый код, если нет, то страшно..

>Соответственно есть два потока: один добавляет в список записи, другой их
>обрабатывает и удаляет. Для выделения/очистки памяти используется *alloc/free.

есть тулза от гугла (google perf tools или как-то так) которая подменяет стандартный malloc на свою реализацию заточеную под очень частое выделение/удаление памяти. Это типо для борьбы с дефрагментацией :)

>Добавление происходит быстрей
>удаления, что естественно ведет к постоянному росту списка, что в конечном
>счете может привести к переполнению памяти. Соответственно вопрос, как этого избежать?

сливать в свап и увеличивать свап, добавить озу, еще добавить озу, юзать темповые файлы, и в конце концов если есть возможность свободно менять код - переписать дизайн.

>Можно ли, например, задать программе (внутри самой программы) какое-то ограничение на
>объем доступной памяти, и при этом, соответственно, определить момент, когда этот
>предел будет достигнут (в этом случае можно было бы делать паузу
>и ждать, пока снова не появится достаточно доступной памяти)?

легко, можно даже снаружи перед запуском задать объем памяти для процесса:

man ulimit ключ -v

дальше если malloc вернет NULL, значит не может выделить, пора возвращать выделенное =)

внутри программы системными вызовами getrlimit, getrusage, setrlimit.


>Кроме того, я пытался использовать процессы вместо потоков и разделяемую память, но
>в этом случае ограничение на объем доступной разделяемой памяти оказался слишком
>маленький (не то 32Мб, не то 64). Может кто-нибудь знает, как
>увеличить это ограничение хотя бы до 2Гб?

видимо ulimit -l :)

>
>И забыл сказать. Программа написана под Red Hat Enterprise Linux 3.0 (ядро
>linux 2.4.21)

достаточно ядра, редкая софтина юзает особые уличный фичи всяких энтерпрайзов и т.п. :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Контроль объема используемой памяти на Си"  
Сообщение от f00l (ok) on 24-Дек-08, 08:03 
>[оверквотинг удален]
>участки памяти всегда разной длины, что ведет к дефрагментации и в
>конечном счете доступно будет гораздо меньше памяти, чем действительно свободно.
>
>Кроме того, я пытался использовать процессы вместо потоков и разделяемую память, но
>в этом случае ограничение на объем доступной разделяемой памяти оказался слишком
>маленький (не то 32Мб, не то 64). Может кто-нибудь знает, как
>увеличить это ограничение хотя бы до 2Гб?
>
>И забыл сказать. Программа написана под Red Hat Enterprise Linux 3.0 (ядро
>linux 2.4.21)

Основная ошибка постоянное выделение и высвобождение памяти (сам с таким сталкивался )
Необходимо выделить память для фиксированного количества данных, и по мере необходимости увеличивать, тогда все будет работать корректно.  

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Контроль объема используемой памяти на Си"  
Сообщение от BigHo on 24-Дек-08, 14:35 
>удаления, что естественно ведет к постоянному росту списка, что в конечном
>счете может привести к переполнению памяти. Соответственно вопрос, как этого избежать?
>Можно ли, например, задать программе (внутри самой программы) какое-то ограничение на
>объем доступной памяти, и при этом, соответственно, определить момент, когда этот
>предел будет достигнут (в этом случае можно было бы делать паузу
>и ждать, пока снова не появится достаточно доступной памяти)? Просто подсчитывать
>количество выделенной памяти ведь не подойдет, так как выделяемые и освобождаемые
>участки памяти всегда разной длины, что ведет к дефрагментации и в
>конечном счете доступно будет гораздо меньше памяти, чем действительно свободно.

Программа играет роль буфера, сглаживающего пиковые нагрузки? Если так, видимо на стадии обработки допущен просчет. Как следует из последующих постов - это может быть неоптимальная конфигурация БД. Если не применять никаких оптимизаций, то скорость работы по INSERT запросам на однодисковой (не RAID) платформе где-то 200-300 запросов в секунду, и с ростом этой таблицы будет только уменьшаться. Я говорю про MySQL, но, думаю, что и для других БД это будет характерно - для БД важна пропускная способность диска, и скорость обработки мелких запросов.

>Кроме того, я пытался использовать процессы вместо потоков и разделяемую память, но
>в этом случае ограничение на объем доступной разделяемой памяти оказался слишком
>маленький (не то 32Мб, не то 64). Может кто-нибудь знает, как
>увеличить это ограничение хотя бы до 2Гб?

Возникает впечатление, что вы пытаетесь бороться с последствиями проблемы, а не самой проблемой,.

По фрагментации памят можно предложить сегментировать её самостоятельно на большие фрагменты: обрабатываемые буфера протяженностью более листа памяти разбивать на секции по размеру системного листа. Если динамический список сделать циклическим, то можно будет по превышению объема памяти свыше установленного лимита - сбрасывать данные на диск, затем их считывать обратно. Естественно, если этот диск уже испытывает значительную нагрузку, то этим проблему можно только усугубить.

С точки зрения постановки задачи более ничего не приходит в голову.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2020 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру