Почему собственная библиотека использует в 1.5 раза больше памяти при использовании Java как тогда, когда используется C-Programm в соответствии с Linux?

Я записал библиотеку в C, который использует большую память (миллионы маленьких блоков). Я записал c программу, которая пользуется этой библиотекой. И я записал программу Java, которая пользуется той же библиотекой. Программа Java является очень тонким слоем вокруг библиотеки. В основном существует только один собственный метод, который называют, делает всю работу и возвращается несколько часов спустя. Нет никакой дальнейшей коммуникации между Java и собственной библиотекой с помощью интерфейса вызова Java. Ни существует объект Java, которые используют примечательный объем памяти.

Таким образом, c программа и программа Java очень похожи. Целое computation/memmory выделение происходит в собственной библиотеке. Все еще. При выполнении c программа использует 3 ГБ памяти. Но программа Java использует 4.3 ГБ! (Сумма VIRT, о которой сообщает вершина)

Я проверил карту распределения памяти процесса Java (использующий pmap). Только 40 МБ используются библиотеками. Таким образом, дополнительные библиотеки, загруженные Java, не являются причиной.

У кого-либо есть объяснение этого поведения?

Править: Спасибо за ответы до сих пор. Сделать это более ясным: код Java действительно только вызывает собственную библиотеку ONCE! "Куча" Java является стандартным размером (возможно, 60 МБ) и не используется (за исключением одного класса, содержащего основной метод и другой класс, вызывающий собственную библиотеку).

Собственный метод библиотеки является длительным и делает много mallocs и освобождает. Фрагментация является одним объяснением, о котором я думал сам также. Но с тех пор нет никакого кода Java, активного, поведение фрагментации должно быть тем же для программы Java и c программы. Так как это отличается, я также предполагаю, что используемые malloc реализации отличаются, когда выполнено в c программе или в программе Java.

7
задан Eduard Wirch 21 January 2010 в 08:27
поделиться

6 ответов

Извините, ребята. Неправильные предположения.

Я привык к 64 МБ реализациям Sun Java, используемых для использования максимального размера кучи по умолчанию. Но я использовал OpenJDK 1.6 для тестирования. OpenJDK использует фракцию физической памяти, если максимальный размер кучи не был явно не указан. В моем случае четвертый. Я использовал 4 ГБ машины. Таким образом, один четвертый 1 ГБ. Там это разница между C и Java.

К сожалению, это поведение нигде не задокументировано. Я нашел его, глядя на исходный код OpenJDK ( ARGUMENTS.CPP ):

// If the maximum heap size has not been set with -Xmx,
// then set it as fraction of the size of physical memory,
// respecting the maximum and minimum sizes of the heap.
2
ответ дан 7 December 2019 в 10:02
поделиться

Просто угадывание: вы можете использовать Malloc Malloc при запуске внутри JVM, который настроен на Специальные потребности JVM и производит больше накладных расходов, чем общего назначения Malloc в вашей обычной реализации LIBC.

3
ответ дан 7 December 2019 в 10:02
поделиться

Существуют разные факторы, которые необходимо учитывать, особенно на языке, такой как Java, Java Runs на виртуальной машине и сборке мусора обрабатывается Java Runtime, так как есть значительные усилия ( Я бы представлял: от использования интерфейса вызова Java для переключения или выполнения нативного метода в нативной библиотеке, поскольку должно быть средством для распределения пространства на стеке, переключаться на нативный код, выполнить нативный метод, переключиться назад Виртуальная машина Java и, возможно, как-то, пространство на стеке не было освобождено - вот что я был бы склонен думать.

Надеюсь, это поможет, С уважением, Том.

0
ответ дан 7 December 2019 в 10:02
поделиться

Трудно сказать, но я думаю, что в самом сердце проблемы в том, что в вашем приложении есть две кучи, которые должны быть Поддержание - стандартная куча Java для ассигнований объекта Java (поддерживается JVM) и Chap Cental C, которое поддерживается вызовами на Malloc / Free. Трудно сказать, что происходит точно, не увидев некоторый код.

0
ответ дан 7 December 2019 в 10:02
поделиться

Java необходимо иметь непрерывную память для его кучи, поэтому она может выделить максимальный размер памяти в качестве виртуальной памяти. Однако это не потребляет физическую память и даже не может потреблять своп. Я бы проверил, насколько ваша резидентская память увеличивается.

1
ответ дан 7 December 2019 в 10:02
поделиться

Вот предложение для борьбы с этим.

Сделайте прекращение кода C с использованием стандартного вызова Malloc, и используйте альтернативную версию Malloc, которая захватывает память MMAP / dev / Zero . Вы можете изменить реализацию MALLOC из библиотеки или катить свои собственные, если вы чувствуете достаточно компетентные, чтобы сделать это.

Я настоятельно подозреваю, что вы обнаружите, что ваша проблема уходит после этого.

0
ответ дан 7 December 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: