"динамические" языки и экономия памяти при подгрузке кода

tokuchu

Я тут чего-то задумался. Вот например в компилируемых языках имеем на выходе shared-библиотеки и таким образом, если несколько процессов используют её, то в памяти будет только 1 экземпляр.
С динамическими же языками как дело обстоит. Ну можно предположить, что в случае всяких виртуальных машин тоже можно этим воспользоваться, если файл с кодом мапить в память, то будет примерно та же технология. Но если там используются JIT или когда нету ВМ, то тоже файл компилируется и это наверняка не "реюзабельно".
Вот интересно — на эту проблему внимание вообще кто-нибудь из разработчиков этих языков обращает и как решают или они её совсем проблемой не считают.

katrin2201

opcode cache?

tokuchu

opcode cache?
чего-чего? :)

vall

если несколько процессов используют её, то в памяти будет только 1 экземпляр.
у этого правила внушительный список исключений, но основные библиотеки типа libc и x11 прекрасно наследуются на экзеке.
данных обычно на порядки больше чем кода --> никого это не волнует, разве что экстремальный эмбедед =)
в jit это может получится побочным эффектом грамотного кэширования прекомпиллированного кода, но думаю как цель такое никто не ставит.

tokuchu

у этого правила внушительный список исключений, но основные библиотеки типа libc и x11 прекрасно наследуются на экзеке.
Разве. shared библиотеки вроде при загрузке просто мапятся в память read-only и соответственно если разные процессы даже от разных юзеров будут её подгружать, то в результате получат один и тот же кусок физической памяти. Но я точно не утверждаю, т.к. знание этого материала у меня лишь поверхностное, но если бы я делал всё правильно, то было бы именно так. :)
данных обычно на порядки больше чем кода.
Ну это в некотором смысле оправдание. Это я и имел в виду, когда говорил "или это не рассматривается как проблема вообще". Но с другой стороны вот взять какой-нибудь простенький Perl-скрипт, который участвует в обработке каких-нибудь транзакций и пользуется внешними модулями, так вот если поток транзакций большой, а данных не так много, то тут уже память будет важна.
в jit это может получится побочным эффектом грамотного кэширования прекомпиллированного кода, но думаю как цель такое никто не ставит.
А как оно осуществляется? Этот прекомпилированный код рядом что ли складывается, чтобы другие могли пользоваться?

vall

пожалуй да, с PIC (Position-independent code) shared всё хорошо
тут у меня знания тоже поверхностные, думал тут тухло как в винде с релокацией.=)
http://www.opennet.ru/base/dev/ldd_linux.txt.html

tokuchu

Гугл? =)
http://en.wikipedia.org/wiki/PHP_accelerator
Ну у пыхпыха-то модули шаред-библиотеками представлены, хотя в случае массивной обработки, безусловно полезно. А эти кеши работают только под одним юзером или между несколькими тоже?

vall

А как оно осуществляется? Этот прекомпилированный код рядом что ли складывается, чтобы другие могли пользоваться?
ну да, байткод пишется рядом в файл, проблемы с резолвом ссылок (если замапилось не по тому адресу) будут теже что в случае бинарных библиотек, но в интерпретаторе их решить проще.
однако придумать реальную ситуацию где этот геморрой будет единственным и необходимым решением я не могу, такое чувство что тут какой-то фундаментальный закон. что типа |.text| = O(t*ln t); |.data| = O(t^2); =)

katrin2201

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

agaaaa

С приходом AMD64 и адресации относительно RIP никаких проблем делать код позиционно-независимым нет.

vall

а что там изменилось принципиально? относительные переходы с большими смещениями?

Serab

а что там изменилось принципиально? относительные переходы с большими смещениями?
Я вообще не понял, о каких проблемах он говорит. Что, теперь с приходом amd64 любой код автоматически позиционно-независимым получиться что ли? Больших проблем не замечал, в общем :smirk:

tokuchu

ну тут и задача несколько иная
ты хотел оптимизацию по памяти, а тут по процу оптимизируют
Ну там что-то написано про то, что байт-код выполняется напрямую из шареной памяти без копирования, т.е. размножения кода тоже не происходит.
В общем понятно, там что-то такое мудрят всё же с этим. Кто ещё какие примеры знает? Perl, ...?

tokuchu

ну да, байткод пишется рядом в файл, проблемы с резолвом ссылок (если замапилось не по тому адресу) будут теже что в случае бинарных библиотек, но в интерпретаторе их решить проще.
Что замапилось не по тому адресу?
Вообще у Жабы ещё проблема обостряется тем, что много кода в сжатом виде хранится, т.е. для такого просто мапить байт-код и пользоваться им без копирования не получится.

katrin2201

Сжатый вид это ты имеешь в виду jarы которые на самом деле zipы?

klyv

они вродь распаковываются во временную папку или в память, используются только для deployment.

katrin2201

В папку только в случае war или ear. jar в память.
Вообще, дело не в этом, а в том, что джавовские *.class - и так байткод и кешировать как бы нечего. А шарить jarы между инстансами jvm'а она точно не умеет.

valodyr

Теперь в качестве базы в M-адресации может использоваться RIP (mov rax, qword ptr [rip + 0x1234]).

tokuchu

Вообще, дело не в этом, а в том, что джавовские *.class - и так байткод и кешировать как бы нечего. А шарить jarы между инстансами jvm'а она точно не умеет.
Ну я и про что говорю, что байткод, если он не меняется в процессе работы, то его можно эффективно в этом смысле использовать, если мапить его в память разными процессами. Тогда перерасхода памяти не будет. Но если оно в архиве, то каждая JVM будет его в память разворачивать в свою. Всякие библиотеки, которые там изкаропки или дополнительно ставятся — они разве не в jar-ах хранятся? Я думал, что так.

klyv

А сколько JVM запущено у тебя?

katrin2201

Всякие библиотеки, которые там изкаропки или дополнительно ставятся — они разве не в jar-ах хранятся? Я думал, что так.
Хранятся то они в джарах, но в мире джава не заморачиваются, и с каждым приложением идет своя копия ВСЕГО не входящего в стандартный jre.
То есть, как правило, общие только jarы входящие в jre.

tokuchu

А сколько JVM запущено у тебя?
У меня, надеюсь, ни одной сейчас. :)
Не в этом суть. Мало ли какие применения можно придумать.

tokuchu

То есть, как правило, общие только jarы входящие в jre.
В общем, всё плохо. :) У каждого своя копия, а то что общее, тоже совместно не попользуешь.

Serab

В общем, всё плохо. :) У каждого своя копия, а то что общее, тоже совместно не попользуешь.
Use .NET, Luke.

tokuchu

Use .NET, Luke.
Не... это я юзать не буду. :p
Тем более, что поставленный вопрос меня чисто теоретически интересует. :)
Как там в .NET с этим, кстати?

Serab

Как там в .NET с этим, кстати?
Ну так я и не советовал в прямом смысле слова юзать .NET, я как раз хотел сказать, что там по этому делу заморачиваются (Microsoft) и там с этим все в поряде, AFAIK, не углублялся в детали реализации.
Т.е. после того как JIT откомпилил функцию, при следующих вызовах (даже из других сборок будет сделан соответствующий fix-up и управление передано к (уже запамленному в адресное пространство нужного процесса) откомпиленному участку.

kokoc88

Т.е. после того как JIT откомпилил функцию, при следующих вызовах (даже из других сборок будет сделан соответствующий fix-up и управление передано к (уже запамленному в адресное пространство нужного процесса) откомпиленному участку.
Мне кажется, что вопрос ставится про многопроцессные системы, а не про другие сборки из того же процесса.

tokuchu

Мне кажется, что вопрос ставится про многопроцессные системы, а не про другие сборки из того же процесса.
Ага, причём не только про многопроцессные, а ещё и многопользовательские. А то если там в пределах одной VM реюз идёт, то этим в детском садике только меряться можно. :)

kokoc88

Вот интересно — на эту проблему внимание вообще кто-нибудь из разработчиков этих языков обращает и как решают или они её совсем проблемой не считают.
Реальные проблемы в .NET могут быть при использовании Linq.Expressions, а также Reflection Emit для решения различных задач по генерации кода, например, для ORM.
С другой стороны, проблемы будут возникать в многопроцессных системах. Но дело в том, что в .NET есть механизмы многопользовательского взаимодействия в рамках одного процесса.

agaaaa

Но дело в том, что в .NET есть механизмы многопользовательского взаимодействия в рамках одного процесса.
Не совсем понял что ты имеешь ввиду, но мне жутко интересно.
Можешь привести пример?

Serab

Ага, причём не только про многопроцессные, а ещё и многопользовательские. А то если там в пределах одной VM реюз идёт, то этим в детском садике только меряться можно. :)
.NET Framework един =) А вот пугание Microsoft проблемами с синхронизацией уж точно детсадовский прием. Какие проблемы с многопроцессными/многопроцессорными системами?

Serab

другие сборки из того же процесса.
об этом я не писал, я же написал просто "другие сборки", где тут указано про тот же процесс?

kokoc88

об этом я не писал, я же написал просто "другие сборки", где тут указано про тот же процесс?
Тогда дай ссылку.

kokoc88

Не совсем понял что ты имеешь ввиду, но мне жутко интересно.
Можешь привести пример?
http://msdn.microsoft.com/en-us/library/43wc4hhs(VS.71).aspx
If an assembly is used by multiple domains in a process, the assembly's code (but not its data) can be shared by all domains referencing the assembly.

Serab

Тогда дай ссылку.
Туше. Ты ловко ведешь беседу. Я сразу же написал, что "подробно не разбирался", где-то что-то запомнил. Если я ошибаюсь, будь добр, поправь, по возможности, конечно со ссылкой.
upd: прошел по ссылке из предыдущего сообщения.
This method of sharing an assembly's code is similar to the way in which the Microsoft Win32 API LoadLibrary shares code pages among processes that reference the same DLL.
наверное мне запомнилось какое-нибудь высказывание наподобие этого и я решил, что там все буквально так.

kokoc88

Я сразу же написал, что "подробно не разбирался", где-то что-то запомнил.
Скорее всего ты "запомнил" про NGen:
 http://msdn.microsoft.com/en-us/magazine/cc163610.aspx
Я это только что нагуглил за тебя... http://www.google.ru/search?hl=ru&newwindow=1&q=net+jit+different+processes&lr=&aq=f&oq=, конечно это не первая, а аж третья ссылка, а так же чтение сообщений других разработчиков и ещё пара кликов.
Про другие механизмы нам может рассказать DarkGray, он наверняка это ботал. :cool:

Serab

Скорее всего ты "запомнил" про NGen:
О. Так и есть, именно эту статью читал с полгода назад. Степень запоминания ты правильно подчеркнул кавычками =)

tokuchu

А вот пугание Microsoft проблемами с синхронизацией уж точно детсадовский прием.
Кто кого пугал проблемами с синхронизацией? Синхронизацией чего? :confused:

serega1604

>А то если там в пределах одной VM реюз идёт, то этим в детском садике только меряться можно. :)
ты знаешь что с каждым Ъ-энтерпрайз приложением IBM идет своя JRE, а системная используется только инсталлятором?

vall

оракл даже для инсталлятора тянет свою

tokuchu

ты знаешь что с каждым Ъ-энтерпрайз приложением IBM идет своя JRE, а системная используется только инсталлятором?
Ну там в этом случае обычно вообще на одной машине одно это приложение запускается в одном экземпляре. Но меня не такие случаи интересуют, я уже писал.
Оставить комментарий
Имя или ник:
Комментарий: