AN> Доброе время суток,
>> А там ключика -g не было при компиляции ?
AN> Спасибо. Зачем его туда влепили?
Ну чтобы core'у исследовать, наверное :-)
>> Какая, по большому счету, разница сколько
>> там кода, если он все-равно весь разделяемый ? Должен волновать размер данных,
>> но их в бинарнике все-равно нет.
AN> То есть, когда top или ps говорят о размере памяти, занимаемой
AN> процессами (httpd) на самом деле это все одна и та же память?
Нет. Не совсем. Это "по большей части" одна и та же память (см. ниже).
AN> А почему они тогда каждый раз разные?
top (или ps) показывают (для Linux'а, но в других *nix'ах обычно все аналогично)
два вида памяти -- SIZE и RSS. При этом SIZE -- это то, что процесс
зарезервировал для себя в своем адресном пространстве (не значит ровным счетом
ничего без дополнительной информации о процессе -- если процесс сделает mmap
файла размеров в 1Gb, то SIZE у него будет в 1Gb, а памяти при этом он может
занимать какую-нибудь фигню), RSS -- в физической. Естественно, что то, что
процессу выделено в виртуальной памяти и досталось в реальной может зависеть
от массы разных причин. Но ни та, ни другая память (как правило) не принадлежат
процессу экслюзивно! Например libc обычно разделяется между всеми (или почти
всеми -- из-за наличия 3 видов активно используемых libc и возможности
статической линковки картина несколько смазывается) процессами. И вообще под
образ библиотеки и/или образ исполняемого файлы место в адресном пространстве
процесса всегда выделается сходу, но вот с диска считывается только то, что
нужно! Поэтому если программа использует пару мелких функций из библиотеки мег
этак на 15-20, то в результате SIZE у процесса будет зубодробительный, а вот
места в памяти он будет занимать весьма немного и с диска при его запуске будет
считаны весьма и весьма ограниченные объемы данных. Потом есть еще
write-on-copy: если процесс делает fork (а Apache ОЧЕНЬ любит делат fork, как
всем прекрасно известно :-), то в сущности создаются только структуры в ядре,
которые положено иметь для задачи (TSS, Page Mapping Table, etc.) и помечаются
все страницы как использующиеся совместно. В тот момент, когда одна из копий
хочет что-нибудь записать создается копия страницы (поддержка этого механизма
есть во всех современных процессорах, включая 486 и выше и даже (с оговорками)
386, так что никаких явных проверок (которые могли бы замедлять работу в
нормальном случае) того, что страница "разделяемая" нигде не делается)...
Корочем понять -- сколько таки процесс занимет памяти в Linux'а (да и в
большинстве современных версий *nix'а) можно но для этого нужно проводить
детективную работу. И ее результат будет действителен ТОЛЬКО для данной
комбинации загруженных в память программ! (Простейший пример: если в памяти
уже загружен, скажем, PostgreSQL, то при загрузке PHP3 с поддержкой PostgreSQL
overhead будет значительно ниже, чем в случае, когда PostgreSQL не загружен,
так как код разделаемой библиотеки PostgreSQL к моменту загрузки PHP3 уже будет
в памяти).
Практическая иллюстрация: у меня mod_perl, mod_php3 и mod_jserv оформлены как
DSO (собственно говоря у меня все что можно оформлено как DSO, но изучать этот
вопрос для стандартных мелких модулей было лень).
Размеры:
mod_php3.so -- 472296
mod_perl.so -- 780436 (туда "вшит" libperl.a -- почему-то в RedHat perl'овая
библиотека поставляется только в статическом виде)
mod_jserv.so -- 16560
При загрузке PHP3 SIZE процессов httpd увеличивается на 572K, RSS на 292K, а
вот суммарный объем потребляемой памяти возрастает всего-то на 124K (это на
6 процессов!).
При загрузке mod_perl SIZE процессов httpd увеличивается на 1592K (статический
libperl.a дает себя знать), RSS на 1588K, а суммарный объем потребляемой
памяти возрастает на 1560K (опять же: статический libperl.a). Я начинаю
подумывать о перекомпиляции perl'а ...
При загрузке jserv'а SIZE процессов httpd увеличивается на 30K, RSS на 24K, а
вот объем потребляемой пямяти возрастает сразу на 2308K за счет отдельно
загружающегося интерпретатора java (тоже надо сказать сильно нехилый процессик:
22712K SIZE (!!!) и 3292K RSS). Кстати здесь особенно ярко проявляется то, что
SIZE не говорит ни о чем почти вообще: учитывая то, что у меня на время
экспериментов была отключена виртуалка и памяти всего 64Mb после загрузки
22Mb (!) интерпретатора java память должна была бы исчерпаться вконец и ни
о какой загрузке после этого X Server'а и Netscape речь бы уже идти не могла...
P.S. Кстати на сильно загруженном сервере для часто используемых скриптов
лучше использовать mod_perl, а не PHP3: первый запуск скрипта mod_perl'ом
происходит существенно дольше, чем PHP3, но он после этого сохраняется в
откомпилированном виде и следующие запросы будут отрабатываться намного
быстрее. С другой стороны если шансы на то, что этот скрипт вскоре потребуется
снова невелики (бывает, но редко при правильном проектировании site'а; например
когда имеется куча .php3 файлов, где PHP3 используется только для учета
различий между реализациями DHTML в MS IE 4.0x и Netscape 4.x), то PHP3
выигрывает -- при однократном запросе простого скрипта (когда ограниченность
языка PHP3 по сравнению с perl'ом не критична) он имеет много меньший overhead.
PHP2 вообще бессмысленен: он действительно имеет несколько меньше кода и
требует чуть меньше пямяти, но работает существенно медленнее и умеет меньше...
"Russian Apache" includes software developed
by the Apache Group for use in the Apache HTTP server project
(http://www.apache.org/) See
Apache LICENSE.
Copyright (C) 1995-2001 The Apache Group. All rights reserved.
Copyright (C) 1996 Dm. Kryukov; Copyright (C)
1997-2009 Alex Tutubalin. Design (C) 1998 Max Smolev.