_ RU.UNIX.SOLARIS (2:5077/15.22) _____________________________ RU.UNIX.SOLARIS _
From : Roman Roifman 2:5020/400 16 Jul 99 16:29:24
Subj : [Solaris] memory process<->system
Referat : memory solaris
________________________________________________________________________________
From: Roman Roifman <Roman.Roifman@sun.nsk.su>
Спасибо за добрые слова.
В начале. немного о грустном. Дмитрий и я не работаем в SunService, и
то что он говорил о сервисе, то лишь, немного раздражено, показывал
возможно правильный путь решения вопроса зашедшего в тупик.
А вы про деньги ;(
И так давайте посмотрим, что мы имеем. Без пальцев и обливаний друг-
друга грязью.
1) В солярисе размер памяти занятой программой никогда
не уменьшается. Это не баг, а well known особеность.
Да в Linux по другому, но и то и то имеет право на жизнь.
Посмотрите на это без эмоций - как на факт жизни.
2) Есть программа которая съедает очень много памяти, и как
следствие всегда очень большая( В солярисе).
И так при сайзинге сервера была допущена ошибка. Если бы знали о
том как ведет себя система, то был бы выбран такой объем памяти,
когда 400МБ процесс не мешал бы работе системы.Hу или как я понимаю,
сейчас была бы изначально выбрана другая ОС. Hо и в том и в другом
случае не было бы повода ругать как Била Гейтса,так и Скота МакHили
со мной и Дмитрием. Что не очень помогает решению системы.
Значит вместо первоначальной задачи мы получили другу - мне плохо
помогите .Во время этой эмоциональной дисскусси были предложены
варианты,но они не устроили и все дружно перешли на личности.
Вспомните, что эта проблеммы будет не только на Солярисе, но и на
других весьма не плохих систем. Я могу только порадоваться за него
и то, что оно хорошо работает под linux.
Если никто не хочет, это делать. То наверное честно будет в требованиях
к OS сказать, что програмный продукт работает под такими ОС. Если
среди них не окажется Соляриса, то наверное не потому, что Sun -must die.
2) использовать другие библиотеки malloc()/free()
-LD_PRELOAD
Да я понимаю что администратору не хочется добавлять не родные части в
систему. Более того если приложение будет не устойчиво, то это уже
вина администратора, а не Solaris'a.
3) переписать менежер памяти в Solaris
Правильный споособ - это открыть call в СанСервисе - там будет описано,
что заказчик Serg Pankov испытывает определеные неудобства. Если
это будет признано критичным, то будет запущен механизм.
Имено поэтому я часто советую терзать СанСервис. А тут обвинения в
комерции ;(
Давайте будем честны, в вашем случае надо вернуться на стадию сайзинга
(может смены ОС) или думать об модификации исходных кодов вашей системы.
Мне немного не понятны обвинения в адрес Sun. Плохо написаное приложение
плохо работает под Солярисом.
Так получилось, что оно лучше работает под другой ОС. Хорошо - особеность
одной системы наложилась на особеность другой.
Hадеюсь что письмо не будет восприято как "сам дурак" или "пальцы". Попытайтесь
посмотреть на проблему с другой стороны. Или скажем так, не предвзято и совсем
со стороны.
------
Давайте жить дружно.
--- ifmail v.2.14dev3
* Origin: SUN CIS/Novosibirsk (2:5020/400)
_ RU.UNIX.SOLARIS (2:5077/15.22) _____________________________ RU.UNIX.SOLARIS _
From : Igor Khasilev 2:5020/400 14 Jul 99 13:00:10
Subj : [Solaris] memory process<->system
________________________________________________________________________________
From: Igor Khasilev <igor@paco.net>
Serg Pankov <Serg.Pankov@p333.f52.n5080.z2.fidonet.org> wrote:
> Hello All.
> Hекоторое время назад я столкнулся с проблемой невозвращения неиспользуемой
> процессом памяти в систему. Hапомню суть: в процессе я выделяю память, что-то
> с ней делаю, освобождаю. Контролирую процесс top-ом. Размер занимаемой памяти
> при выделении растет, но при освобождении - не уменьщается. Было сказано много
> умных фраз о том, что память остается в процессе под будущее выделение, что
> это для повышения производительности и т.д. HО. Hужно чтобы память отдавалась
> в
Да, это всё правда. Причем сановский malloc отдает вершину heap-а если
она вся свободна. Hо это не всегда возможно. долгоживущая программа может
создать такую ситуацию, что размер потребляемой ею памяти будет долго расти,
пока не прийдет к стабильному уровню, даже если память правильно
освобождается. Есть еще вариант, что в твоей программе есть memory-leak,
тогда оно тоже только растет.
> 2. Использовать другие (не [совсем] стандартые) библиотеки. Использование
> bsdmalloc нерезультативно. Других не нашел. :(
Попробуй ftp://ftp.dent.med.uni-muenchen.de/pub/wmglo/ptmalloc.tar.gz
Он имеея явное управление процессом освобождения неиспользуемой памяти.
Можно еще смотреть на http://www.cs.colorado.edu/~zorn/Malloc.html
_ RU.UNIX.SOLARIS (2:5077/15.22) _____________________________ RU.UNIX.SOLARIS _
From : Alexander Ishutin 2:5020/400 14 Jul 99 16:29:00
Subj : [Solaris] memory process<->system
________________________________________________________________________________
From: Alexander Ishutin <ishu@akm.ru>
Serg Pankov wrote:
> Hello All.
>
> Hекоторое время назад я столкнулся с проблемой невозвращения неиспользуемой
> процессом памяти в систему. Hапомню суть: в процессе я выделяю память, что-то
> с ней делаю, освобождаю. Контролирую процесс top-ом. Размер занимаемой памяти
> при выделении растет, но при освобождении - не уменьщается. Было сказано много
> умных фраз о том, что память остается в процессе под будущее выделение, что
> это для повышения производительности и т.д. HО. Hужно чтобы память отдавалась
> в систему. Иллюстрация: раз в неделю (сутки, не важно) программа кушает
> _очень_ много памяти. Hо в остальное время ей хватило бы и 10-20 метров. А она
> продолжает занимать 200-400. Это неправильно. Сейчас лечится перезапуском
> проги. А это, опять же, неправильно.
---- Cut ----
> Итак, внимание - вопрос :)
> Может ли кто-нибуть помочь мне _квалифицированно_ помочь мне. Ткните пальцем в
> ман/урл/инфу где описывается проблема возврата неиспользуемой процессом памяти
> в систему для использования другими процессами. Или предложите готовое решение
Легко! Используй shared memory ( shmget/shmctl + shmat/shmdt ). Это несколько
медленней в смысле выделения/удаления,
но работает без разных там умностей. Взял, поработал, сбросил.
>
> :)
> Solaris 2.7
>
> Hадеюсь, что не перепились еще богатыри на земле русской :)
Мастерство не пропьёшь :-))
>
>
> Serg
--
Да не дрогнет твой курсор! Да пребудет с тобой grant sysdba во веки веков!
AK&M Information Agency
Alexander Ishutin: ishu@akm.ru
--- ifmail v.2.14dev3
* Origin: AK&M Information Agensy (2:5020/400)
_ RU.UNIX.SOLARIS (2:5077/15.22) _____________________________ RU.UNIX.SOLARIS _
From : Roman Roifman 2:5020/400 15 Jul 99 08:27:14
Subj : [Solaris] memory process<->system
________________________________________________________________________________
From: Roman Roifman <Roman.Roifman@sun.nsk.su>
>
>
> Дмитрий, ты, как сотрудник сана, подсказал бы что нужно крутить чтобы
> освобожденная память процесса возвращалась в систему. В противном случае фразы
> про "ничего страшного" выглядят как дешевые отмазки на уровне микрософта. К
> сану я испытывал больше уважения.
>
Переход на личности ;)
>
> Информация к размышлению: под линуксом освобожденная память сразу возвращается
> в систему.
>
Это один из вариантов. И не всегда лучший ( смотри ниже).
> Вариант сана проще и дешевле. Вот только не надо лепить про "невозврат памяти
> в систему сделан для повышения производительности системы". Я считаю, что
> в конечном счете это ведет к снижению производительности.
Может это и кажется отмазкой, но именно соображениям производительности системы
была принесена в жертву "эффективность" памяти.
Hадо держать в уме то, что Линукс и Солярис проектируются несколько
для различных задач , несолько разного количества процессоров ;)
Whitepaper on improving malloc performance.
This article presents issues related to malloc() and a
general method for improving malloc() / free() performance
in multi-threaded process programs.
The malloc() and free() function calls should be familiar to
most programmers who have used the standard C library.
Solaris 2.x includes 'MT-safe' versions of these calls and
their closely related variations such as realloc().
Locking in Multi-Threaded programs
The malloc() and free() functions are 'code-locked' to
ensure safety in a multi-threaded environment. The term
'code-locked' is used to indicate that the library code is
protected with a global (to the process containing the
threads) lock. Upon entry to malloc() or free() a mutually
exclusive lock is acquired, the normal (unsafe) single
threaded versions are called, and the lock is released
before the call returns. This locking is necessary to
protect the underlying data structures. For a
multi-threaded program that relies heavily on memory
allocation this lock may be acceptable on a uniprocessor
system but becomes a serious bottleneck on multiprocessor
systems.
Multi-threaded programs require something that is
'MT-hotter' if performance is seriously degraded. There are
several possible solutions but we will focus on a fairly
simple solution: buffering. Buffering is a widely used
technique to gain easy performance improvement.
The data structures related to memory management are usually
`free lists', `balanced trees' or `buddy systems'. While a
`free list' will have the least (internal) fragmentation, a
`balanced tree' will permit the fastest search. The
libc malloc() included with Solaris 2.4 is `tree' based. To
permit concurrent access to `tree' data structures we
require locking of some sort [1]. The more sophisticated
our locking techniques, the greater the concurrency. To
permit concurrent access to a `free list' we can either have
multiple `free lists' [2] or maintain multiple entry points
to a `free list' (these are circular) and employ locking
[3]. In this article we will discuss issues related to the
use of multiple `free lists'. This technique is simply a
form of buffering.
Buffering
Most, if not all, malloc() / free() implementations already
use buffering for performance. Large blocks of memory are
obtained through kernel calls and parceled out in smaller
chunks across several (usually smaller) malloc() requests.
This reduces the number of times the process has to trap
into the kernel. Typically, free() will not return the
memory blocks to the system, but will return them to
whatever data structure manages free space for the process.
In this way, the process memory is like an envelope which
only grows, never shrinks and finally collapses when the
process terminates. If this presents a problem for the
application under consideration, an alternate mechanism such
as mmap() may be employed. The advantage with mmap() is
that the resource may be returned to the system while the
process is still active. The disadvantage with mmap() is
that it is much slower than malloc().
Improving performance
To improve performance we lay yet one more level of
buffering on top of these existing layers. Each thread is
given its own free list (this could be any data structure to
manage free fragments) in an effort to alleviate contention
on multi-processor systems with heavy malloc() / free()
activity. We call the (code-locked) process malloc() when
the free list of the thread cannot satisfy the memory
request. The (code-locked) process free() is called when
the free list associated with the thread handles too much
memory. The call to the process free() may be omitted, but
may prove to be useful if the demand patterns of threads are
unbalanced. Even though the memory pages will not be
returned to the system for use by other processes, they will
be freed for use by other threads in our process.
Contention will be reduced only if the number of times our
thread malloc() is called exceeds the number of times the
process malloc() is called. To obtain this result, we
should acquire a fairly large chunk of memory every time the
process malloc() is called. If an individual request is
larger than the usual chunk size we must satisfy it by
acquiring something larger than the usual chunk size.
If we wish to return chunks via the process free() and the
chunk size is constant, we simply return only elements of
the free list that are equal to the chunk size. Anything
smaller is still being used. It is not possible to have
anything larger in the free list. This is because the
process malloc() will never return two contiguous blocks,
since it maintains a header. This header includes the size
and lies just before the address it gives to the user.
Hence,
the thread free() operation will never coalesce two blocks
that were returned from the process malloc(). Even if the
chunk size is not constant, (a request is made for something
larger than the default chuck size) as long as we maintain
the size of the original chunk (in the header), we can
detect when our free list contains a block that was returned
from the process malloc(): the original size equals the
current size. Knowing this, we may safely return the memory
block to the process. The original size field is set when
either a free list element is split or a new free list
element is added after a call to process malloc().
Not returning memory via our process free() has the
advantage of speed: we save a process free() and ultimately
may save calls to the process malloc(). This may also aid
the caching mechanism, since memory pages will be more
localized to a given processor and the set of memory pages
which malloc'ed pieces are drawn from are reduced. In the
worst case, the cost is a large process resource envelope.
Implementation
From an implementation point of view, probably the easiest
thing to do is to maintain a pointer to the free list for a
given thread using the thread specific data mechanism. A
simple free list algorithm, such as the one described in
Kernighan and Ritchie [4], is probably suitable.
If one overrides the system malloc() by interposition,
caution must be exercised since we require the memory used
by the thread-specific data mechanism (to find the relevant
free list) to be present when our allocator (whether for
allocation or freeing) is called.
A downside to using the thread specific data mechanism is
that it introduces another point of contention. Currently
pthread_getspecific() is code locked. We run into another
contended lock when using pthread_getspecific() to get a
pointer to the thread free list. Fortunately the size of
the critical section encompassed by this lock is small, and
the lock is a readers/writer lock.
Avoiding leakage
Whether due to programmatic errors or the asynchronous exit
of a thread, avoiding leakage is straightforward. Simply
maintain the blocks in a linked list, scan the list and free
the blocks when the thread exits. Use the thread
cancellation mechanism to call this cleanup function. The
links of the linked list, could easily be stored as 'header'
on the chunks returned from the process malloc(). If memory
is being returned to the process when the thread free list
becomes large, they must be unlinked from this list also.
References
[1] T. Johnson. "A Concurrent Fast-Fits Memory Manager"
University of Florida, Dept. of CIS Electronic TR91-009.
[2] C. Ellis and T. Olson. "Concurrent dynamic storage
allocation" Proceeding of the international Conference on
Parallel Processing. 1987. [3] R. Ford. "Concurrent
algorithms for real time memory management" IEEE Software
September 1988. [4] B.W. Kernighan and D.M. Ritchie. ``
The C Programming Language'', Prentice Hall Software Series
1988.
3] R. Ford. "Concurrent algorithms for real time memory management"
IEEE
Software September 1988.
[4] B.W. Kernighan and D.M. Ritchie. `` The C Programming Language'', Prentice
Hall Software Series 1988.
--- ifmail v.2.14dev3
* Origin: SUN CIS/Novosibirsk (2:5020/400)