Подтвердить что ты не робот

Как профиль памяти в Java?

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

Итак, вот что я сделал, я добавил точку останова к началу моей программы и запустил ее, после чего начал работу visualVM и профилировал память (я тоже делал то же самое в netbeans только для сравнения результатов, и они одинаковы). Моя проблема заключается в том, что я не знаю, как их читать, я получил самую высокую область, просто говоря char[], и я не вижу никакого кода или чего-либо (что имеет смысл, потому что visualvm подключается к jvm и не может видеть мой source, но netbeans также не показывает мне источник, как при выполнении профилирования cpu).

В принципе, я хочу знать, какая переменная (и, надеюсь, более подробная информация о том, какой метод) использует всю память, поэтому я могу сосредоточиться на работе там. Есть ли простой способ сделать это? Я сейчас использую eclipse и java для разработки (и установленных visualVM и netbeans специально для профилирования, но я готов установить что-нибудь еще, что, по вашему мнению, выполняет эту работу).

EDIT: В идеале, я ищу что-то, что возьмет все мои объекты и отсортирует их по размеру (так что я могу видеть, какая из них представляет собой память для hogging). В настоящее время он возвращает общую информацию, такую ​​как string [] или int [], но я хочу знать, к какому объекту относится его ссылка, поэтому я могу работать над тем, чтобы его размер был более оптимизирован.

4b9b3361

Ответ 1

Строки являются проблематичными

В основном в Java, String ссылки (вещи, которые используют char[] за кулисами) будут доминировать над большинством бизнес-приложений. Как они создаются, определяет, сколько памяти они потребляют в JVM.

Просто потому, что они настолько фундаментальны для большинства бизнес-приложений, как тип данных, и они являются одними из самых голодных. Это не просто вещь Java, а типы данных String занимают много памяти в большинстве языков и библиотеки времени выполнения, потому что по крайней мере они представляют собой только массивы по 1 байт на символ или в худшем случае (Unicode), они представляют собой массивы с несколькими байтами на символ.

Как только при профилировании использования ЦП в веб-приложении, в котором также была зависимость от JDBC, я обнаружил, что StringBuffer.append() доминировал над циклами ЦП на много порядков по сравнению со всеми другими вызовами методов , а тем более любой другой вызов одного метода. Драйвер JDBC сделал много и много манипуляций String, вроде компромисса с использованием PreparedStatements для всего.

Что вас беспокоит, вы не можете контролировать, а не напрямую в любом случае

То, на что вы должны сосредоточиться, - это то, что находится под вашим контролем, которое гарантирует, что вы не держитесь за ссылки дольше, чем вам нужно, и что вы не дублируете вещи без необходимости. Процедуры сбора мусора на Java очень оптимизированы, и если вы узнаете, как работают их алгоритмы, вы можете убедиться, что ваша программа ведет себя оптимальным образом для работы этих алгоритмов.

Java Heap Memory не похожа на управляемую вручную память на других языках, эти правила не применяются

То, что считается утечкой памяти на других языках, - это не одно и то же/первопричина, как в Java с его системой сбора мусора.

Скорее всего, в памяти Java не потребляется один единственный uber-объект, который протекает (оборванная ссылка в других средах).

Это, скорее всего, много меньших распределений из-за StringBuffer/StringBuilder объектов, не соответствующих размерам для первых мгновений, а затем для автоматического создания массивов char[] для последующего вызова append().

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

ПРИМЕР: сборщик мусора может решить, что есть кандидаты, но поскольку он считает, что еще много памяти, чтобы было слишком дорогое время, чтобы сбросить их с помощью этого момент времени, и он будет ждать, пока давление в памяти будет выше.

Сборщик мусора действительно хорош сейчас, но это не волшебство, если вы делаете дегенеративные вещи, это заставит его работать не оптимально. В Интернете есть много документации о настройках сборщика мусора для всех версий JVM.

Эти объекты без ссылки могут просто не дойти до того времени, когда сборщик мусора считает, что им нужно, чтобы они были удалены из памяти, или могут быть ссылки на них, удерживаемые каким-либо другим объектом (List) для Например, вы не понимаете, что все еще указывает на этот объект. Это то, что чаще всего упоминается как утечка в Java, которая является скорее утечкой ссылок.

ПРИМЕР:. Если вы знаете, что вам нужно построить 4K String с помощью StringBuilder создать его с new StringBuilder(4096);, а не по умолчанию, то есть 32, и сразу начнет создавать мусор, который может представлять много раз то, что, по вашему мнению, должен быть размером по размеру.

Вы можете узнать, сколько объектов создаются с помощью VisualVM, это скажет вам, что вам нужно знать. Не будет одного большого проблескового света, указывающего на один экземпляр одного класса, который говорит: "Это большой потребитель памяти!", То есть, если только один экземпляр какого-либо char[], который вы чтение массивного файла, и это невозможно, потому что многие другие классы используют char[] внутренне; и тогда вы в значительной степени знали об этом.

Я не вижу упоминания о OutOfMemoryError

У вас, вероятно, нет проблем в коде, система сбора мусора просто не может быть поставлена ​​под достаточное давление, чтобы ударить и освободить объекты, которые, по вашему мнению, должны быть очищены. Что вы думаетепроблема, вероятно, не такова, если только ваша программа не сработает с помощью OutOfMemoryError. Это не C, С++, Objective-C или любой другой язык управления ручной памятью/время исполнения. Вы не можете решить, что находится в памяти или нет, на уровне детализации, который вы ожидаете, вы должны быть в состоянии.

Ответ 2

В JProfiler вы можете перейти к кучеру и активировать самый большой вид объектов. Вы увидите, что объекты сохраняют большую часть памяти. "Сохраненная" память - это память, которая была бы освобождена сборщиком мусора, если вы удалили объект.

Затем вы можете открыть узлы объектов, чтобы увидеть дерево ссылок сохраняемых объектов. Здесь показан снимок самого большого объекта:

enter image description here

Отказ от ответственности: моя компания разрабатывает JProfiler

Ответ 3

Я бы рекомендовал захватить кучи кучи и использовать такой инструмент, как Eclipse MAT, который позволяет анализировать их. Существует множество учебных пособий. В нем дается представление о дереве доминирования , чтобы обеспечить понимание взаимосвязей между объектами в куче. В частности, для того, что вы упомянули, функция "путь к GC-корням" MAT расскажет вам, куда ссылаются большинство этих объектов char [], String [] и int []. JVisualVM также может быть полезен при определении утечек и распределений, в частности, путем использования моментальных снимков с трассировкой стека распределения. Существует немало проходов процесса получения снимков и их сравнения, чтобы найти точку выделения.

Ответ 4

Java JDK поставляется с JVisualVM под папкой bin, как только ваш сервер приложений (например, запущен) вы можете запускать visualvm и подключать его к локальному хосту, что обеспечит вам выделение памяти и позволит вам выполнить сброс кучи

введите описание изображения здесь

Подробнее о том, как включить: http://sysdotoutdotprint.com/index.php/2017/08/01/turn-profiler-java/

Ответ 5

Если вы используете visualVM для проверки использования вашей памяти, он фокусируется на данных, а не на методах. Возможно, ваши большие данные char [] вызваны многими значениями String? Если вы не используете рекурсию, данные не будут получены из локальных переменных. Поэтому вы можете сосредоточиться на методах, которые вставляют элементы в большие структуры данных. Чтобы узнать, какие точные утверждения вызывают "утечку памяти", я предлагаю вам дополнительно