- Контроль объема используемой памяти на Си, Andrey Mitrofanov, 13:18 , 23-Дек-08 (1)
>Добавление происходит быстрей удаления, что естественно ведет к постоянному росту > к переполнению памяти. Соответственно вопрос, как этого избежать?Неужели удалять быстрее, чем добавляешь?? Может быть, подумать, кой чорт понёс^W^W^Wзачем тебе понадобились потоки/форки? Сделать _выводы_. Например, читать-писать _последовательно_ в __одном__ потоке. Или исхитриться и читать двумя или более потоками, коли уж один "не успевает" (это не избавляет от необходимости синхронизации/блокировки ресурсов или какого ни IPC; и разнесения читателей по разным cpu). Оптимизировать производительность читателя, чтоб успевал. Купить сервер, чтоб успевал. Купить много серверов, чтоб успевали. Ещё ускорять читателя - отложить часть работы, например, "синхронно" писать на диск, потом медленно/асинхронно оборабатывать. Диск он большой -- авось поместится. 100рублейвкассублин! 2Maxim Chirkov: Гы, куда страждущим переводить _деньги_ за консультацию? Заведи кошелёк opennet что ли?.. %-)) И доп.поле "[_ ] руб. в кассу!", и ключь-идентификатор для вписывания в квиток %) перевода, и "лампочку" [ОПЛАЧЕНО] на ответах. :D Желаю анонимно зарабатывать денег уважаемому сайту и немеряной, но оцененной Славы. Как бы ещё анонимных неплательщиком пиночить? %) >конечном счете доступно будет гораздо меньше памяти, чем действительно свободно. Феерично....... >Может кто-нибудь знает, как увеличить это ограничение хотя бы до 2Гб? Вам, может быть, нужен програмист? >И забыл сказать. Программа написана под Red Hat Enterprise Linux 3.0 (ядро linux 2.4.21) Не-е-е, в интырпрайз программировании тут никто ничего не понимает... Это Вам на бизнес-кусы надо.
- Контроль объема используемой памяти на Си, Virius, 14:05 , 23-Дек-08 (2)
Видимо моя ошибка, что не описал задачу подробней. Хотя и причин для смеха в своем текте я не нахожу.>Неужели удалять быстрее, чем добавляешь?? > >Может быть, подумать, кой чорт понёс^W^W^Wзачем тебе понадобились потоки/форки? Сделать _выводы_. > Удаляю я как раз медленней, о чем и написал. Потому что первый поток только добавляет, а второй еще и обработкой занимается с записью обработанных данных в БД. Из-за работы с БД основные тормаза и идут. Поэтому и используется конвеер, чтобы успевать принимать данные. И в данный момент используются процессы (форки) с промежуточным буфером в разделяемой памяти. И тут-то встала проблема, что в разделяемой памяти буфер может быть не больше 32/64Мб. Как увеличить этот предел - мне не известно. Хочу перевести это дело на потоки, так как с потоками все данные находятся в одном адресном пространстве, но встает проблема с тем, как контралировать заполнение памяти так, чтобы не прейти к переполнению. >Например, читать-писать _последовательно_ в __одном__ потоке. Или исхитриться и читать двумя или >более потоками, коли уж один "не успевает" (это не избавляет от >необходимости синхронизации/блокировки ресурсов или какого ни IPC; и разнесения читателей по >разным cpu). Оптимизировать производительность читателя, чтоб успевал. Купить сервер, чтоб успевал. >Купить много серверов, чтоб успевали. Ещё ускорять читателя - отложить часть >работы, например, "синхронно" писать на диск, потом медленно/асинхронно оборабатывать. Диск он >большой -- авось поместится. > Двумя и более потоками читать не получится. Слишком муторно и труднореализуемо, если вообще реализуемо. Мощность сервера и без того достаточная. Вся загвоздка в том, что данные приходят быстрей, чем программа, успевает их записать в БД. Тут все утыкается в производительность дискового массива, который используется для хранения БД, но его заменить щас не возможно. Да и замена его на более быстрый думаю не сильно бы помогла. Поэтому все опять же возвращается к означенным мной ранее вопросом, на которые я надеюсь кто-нибудь таки сможет мне ответить.
- Контроль объема используемой памяти на Си, pavel_simple, 07:32 , 24-Дек-08 (4)
1. менять дизайн проги по любому -- т.к. передача данных от процесса к процессу не есть верный способ. 2. у современных БД есть асинхронные вызовы 3. если БД не успевает это записывать из-за диска это одно, если из-за того что не оптимизированы запросы/таблицы это другое 4. если БД оптимизировать нельзя, и запись не успевает нужно менять железо как не подходящее для задачи. всё это напоминает решение задачи "считаем трафик", только через Ж
что хоть прога делает? -- частенько встречаются случаи с неверной постановкой задачи и соответствующей реализацией
- Контроль объема используемой памяти на Си, vic, 22:54 , 23-Дек-08 (3)
>Всегда были проблемы при работе с памятью, и сейчас возник следующий вопрос. Изучайте матчасть и закрывайте пробелы. >У меня в программе на Си в 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) достаточно ядра, редкая софтина юзает особые уличный фичи всяких энтерпрайзов и т.п. :) - Контроль объема используемой памяти на Си, f00l, 08:03 , 24-Дек-08 (5)
>[оверквотинг удален] >участки памяти всегда разной длины, что ведет к дефрагментации и в >конечном счете доступно будет гораздо меньше памяти, чем действительно свободно. > >Кроме того, я пытался использовать процессы вместо потоков и разделяемую память, но >в этом случае ограничение на объем доступной разделяемой памяти оказался слишком >маленький (не то 32Мб, не то 64). Может кто-нибудь знает, как >увеличить это ограничение хотя бы до 2Гб? > >И забыл сказать. Программа написана под Red Hat Enterprise Linux 3.0 (ядро >linux 2.4.21) Основная ошибка постоянное выделение и высвобождение памяти (сам с таким сталкивался ) Необходимо выделить память для фиксированного количества данных, и по мере необходимости увеличивать, тогда все будет работать корректно. - Контроль объема используемой памяти на Си, BigHo, 14:35 , 24-Дек-08 (6)
>удаления, что естественно ведет к постоянному росту списка, что в конечном >счете может привести к переполнению памяти. Соответственно вопрос, как этого избежать? >Можно ли, например, задать программе (внутри самой программы) какое-то ограничение на >объем доступной памяти, и при этом, соответственно, определить момент, когда этот >предел будет достигнут (в этом случае можно было бы делать паузу >и ждать, пока снова не появится достаточно доступной памяти)? Просто подсчитывать >количество выделенной памяти ведь не подойдет, так как выделяемые и освобождаемые >участки памяти всегда разной длины, что ведет к дефрагментации и в >конечном счете доступно будет гораздо меньше памяти, чем действительно свободно. Программа играет роль буфера, сглаживающего пиковые нагрузки? Если так, видимо на стадии обработки допущен просчет. Как следует из последующих постов - это может быть неоптимальная конфигурация БД. Если не применять никаких оптимизаций, то скорость работы по INSERT запросам на однодисковой (не RAID) платформе где-то 200-300 запросов в секунду, и с ростом этой таблицы будет только уменьшаться. Я говорю про MySQL, но, думаю, что и для других БД это будет характерно - для БД важна пропускная способность диска, и скорость обработки мелких запросов. >Кроме того, я пытался использовать процессы вместо потоков и разделяемую память, но >в этом случае ограничение на объем доступной разделяемой памяти оказался слишком >маленький (не то 32Мб, не то 64). Может кто-нибудь знает, как >увеличить это ограничение хотя бы до 2Гб? Возникает впечатление, что вы пытаетесь бороться с последствиями проблемы, а не самой проблемой,. По фрагментации памят можно предложить сегментировать её самостоятельно на большие фрагменты: обрабатываемые буфера протяженностью более листа памяти разбивать на секции по размеру системного листа. Если динамический список сделать циклическим, то можно будет по превышению объема памяти свыше установленного лимита - сбрасывать данные на диск, затем их считывать обратно. Естественно, если этот диск уже испытывает значительную нагрузку, то этим проблему можно только усугубить. С точки зрения постановки задачи более ничего не приходит в голову.
|