Вопрос по visualvm, java, profiling – Как сохранить профиль памяти в Java?

28

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

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

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

РЕДАКТИРОВАТЬ: В идеале, я ищу что-то, что будет брать все мои объекты и сортировать их по размеру (чтобы я мог видеть, какой из них утомляет память). В настоящее время он возвращает общую информацию, такую как string [] или int [], но я хочу знать, на какой объект он ссылается, чтобы я мог работать над тем, чтобы оптимизировать его размер.

без использования чего-либо, что будет использоваться в вашем коде, никакой анализатор не сможет указать, какой именно экземпляр == то, что вы называете ссылкой в своем источнике. user177800
Я использую профилировщик, который показывает мне, где размещаются объекты. Я не знаю, может ли VisualVM сделать это, но это очень полезно. Я использую YourKit, но он не бесплатный (но вы можете получить лицензию eval) Peter Lawrey
@PeterLawrey Я на самом деле прочитал ответ, который вы написали некоторое время назад, где вы упомянули, что yourkit был вашим первым выбором, я его искал (поскольку ваш совет всегда потрясающий), но да, он немного дорогой, и я только учусь. Error_404

Ваш Ответ

4   ответа
24

Strings are problematic

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

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

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

What you are concerned about you can't control, not directly anyway

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

Java Heap Memory isn't like manually managed memory in other languages, those rules don't apply

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

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

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

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

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

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

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

EXAMPLE: Если вы знаете, что вам нужно построить 4KString используяStringBuilder создать его сnew StringBuilder(4096); не по умолчанию, который равен 32 и сразу же начнет создавать мусор, который может многократно представлять то, что, по вашему мнению, должно соответствовать размеру объекта.

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

I don't see any mention of OutOfMemoryError

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

8

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

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

enter image description here

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

2

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

enter image description here

Для более подробных шагов о том, как включить: http://sysdotoutdotprint.com/technologies/java/6

2

мент, какEclipse MAT это позволяет вам анализировать их. Здесь очень многоучебные пособия имеется в наличии. Это обеспечивает вид надерево доминатор чтобы дать представление об отношениях между объектами в куче. Специально для того, что вы упомянули, «путь к корням GC» Функция MAT подскажет вам, где находятся ссылки на большинство объектов char [], String [] и int []. JVisualVM также может быть полезен при выявлении утечек и распределений, особенно с использованием моментальных снимков со следами стека выделения. Есть немалопрохождение процесса получить снимки и сравнить их, чтобы найти точку распределения.

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