2008-09-19 5 views
2

У меня есть часть приложения, написанная на C, она запускает JVM и использует JNI для взаимодействия с Java-приложением. Мой объем памяти через Process Explorer достигает 1 ГБ и заканчивается из памяти. Теперь, насколько я знаю, он должен иметь возможность получить до 2 ГБ. Я считаю, что память, которую использует JVM, не видна в Process Explorer. Мой xmx установлен на 256, я добавил некоторые заявления, чтобы посмотреть боковую память java, и он достигает максимума на 256, а GC выполняет свою работу, и с этой стороны все хорошо. Поэтому мой вопрос: где потребляется еще 700 МБ? Кто-нибудь есть эксперт по Java/JNI/C Memory?Проблемы с памятью с использованием JAVA, JNI и C

+0

У JVM заканчивается память или процесс Windows? – Alexander

+0

Windows-процесс – drye

+0

на самом деле, свободная от Java память и только около 60 МБ, когда заканчивается сторона C. – drye

ответ

0

Напишите тестовую жгут C и используйте valgrind/alleyoop для проверки на утечку в вашем коде C и аналогичным образом используйте инструмент java jvisualvm.

0

Код C и JNI также может выделять память (malloc/free/new/etc), которая находится за пределами 256-бит VM. XMX ограничивает только то, что VM будет выделять. В зависимости от того, что вы выделяете в коде C и какие другие вещи загружены в память, вы можете или не сможете получить до 2 ГБ.

0

Если вы говорите, что это процесс Windows, который исчерпывает память, а не JVM, то моя первоначальная догадка заключается в том, что вы, вероятно, ссылаетесь на некоторые собственные (собственные) собственные методы из JVM и те собственные утечки памяти. Итак, я согласен с @John Gardner здесь.

+0

Ну, насколько я могу судить, сторона C получает 1 ГБ, JVM использует 256 МБ, поэтому 1024 + 256 = 1280. Я ожидал бы, что смогу использовать 768 больше. Где потребляется 768 МБ, если он не используется на стороне С и он не используется JVM. – drye

1

В коде JNI может быть утечка.

Не забудьте использовать (* jni) -> DeleteLocalRef() для любых ссылок на объекты, которые вы получаете, когда закончите с ними. Если вы используете любые собственные буферы C для создания новых объектов Java, убедитесь, что вы освобождаете их после создания объекта. Ознакомьтесь с Спецификацией JNI для получения дополнительных рекомендаций.

В зависимости от используемой виртуальной машины вы можете включить проверку JNI. Например, в IBM JDK вы можете указать «-Xcheck: jni».

1

Попробуйте тестовое приложение на C, которое не порождает JVM, но вместо этого пытается выделить все больше и больше памяти. Посмотрите, может ли тестовое приложение достичь барьера на 2 ГБ.

+0

Я дал вам голосование по этому поводу, так как я сделал это испытание. Я также выделил 1,4 ГБ перед запуском JVM, и, пытаясь запустить JVM, он не смог выделить достаточное количество памяти для объекта HEAP. Поэтому я пришел к выводу, что HEAP захватывает невидимую память. – drye

+0

Итак, проверьте, сколько памяти используется для сопоставления памяти всех динамических библиотек, используемых JVM и вашим приложением C. Может быть, именно эта память виновата. – Alexander

0

Хорошо благодаря всей вашей помощи, особенно @alexander. Я обнаружил, что вся дополнительная память, которая не видна в Process Explorer, используется Java-кучей. Фактически с помощью других тестов, которые я запускал, потребление памяти JVM включено в то, что я вижу из Process Explorer. Таким образом, куча требует больших объемов памяти, мне придется сделать еще несколько исследований об этом и, возможно, задать отдельный вопрос.