|
|
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
День добрый! Имею Heap Dump в Visual VM. Возникают вопросы: 1) Не понимаю что показывает VisualVM в графе суммарный сайз в разделе "по классам". Как известно, там показывается список классов и рядом размер памяти, занимаемый инстансами этих классов. Вопрос: это полная память которую занимают инстансы этих классов, или это память без вложенных в эти инстансы объектов других классов? Допустим, в анализаторе написано что массивы char[] занимает 40% памяти. Как я понимаю, эти массивы могут быть или локальными переменными в каких-то методах, или быть полями каких-то классов. Следовательно, может быть инстансы какого-то класса занимают эти 40% памяти, или два по 20% итд. Вот я и хочу понять что это за классы. Собственно это второй вопрос: 2) В куче много объектов int[], char[] итд. Они занимают наибольшее место. Однако я не знаю откуда они берутся. Как мне это понять? Я предполагаю, что можно написать запрос на OQL, который выведет все объекты, хранящие массивы примитивов и отсортирует их по суммарной памяти которую они занимают. Как написать такой запрос? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 15:05 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
Сохраняйте этот дамп и открывайте его в Eclipse Memory Analyzer, а там первым делом Dominator Tree. Разглядывать масивы в Visual VM - пустое занятие ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 15:14 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
Dymytry1) Не понимаю что показывает VisualVM в графе суммарный сайз в разделе "по классам". Как известно, там показывается список классов и рядом размер памяти, занимаемый инстансами этих классов. Вопрос: это полная память которую занимают инстансы этих классов, или это память без вложенных в эти инстансы объектов других классов? На сколько я помню в VisualVM просто размер, без внутренних классов (то есть размер поля это размер ссылки, а не размер объекта, на который поле ссылается). Не помню, умеет ли VisualVM, но в YourKit есть ещё и оценочный полный размер с внутренностями. DymytryДопустим, в анализаторе написано что массивы char[] занимает 40% памяти. Как я понимаю, эти массивы могут быть или локальными переменными в каких-то методах, или быть полями каких-то классов. Это скорее всего строки. Если их много, от по количеству объектов типа String будет это видно. Или CLOB-ы. Dymytry2) В куче много объектов int[], char[] итд. Они занимают наибольшее место. Однако я не знаю откуда они берутся. Как мне это понять? Я предполагаю, что можно написать запрос на OQL, который выведет все объекты, хранящие массивы примитивов и отсортирует их по суммарной памяти которую они занимают. Как написать такой запрос? Нет. Открываешь список всех классов - выбираешь что нужно int[] или char[]. Даблклик - получаешь список всех экземпляров этого типа. В списке роешься, смотришь содержимое - уже по содержимому можно понять что это за строки (char[]) и что в них. Выбираешь самые типичные, которых в памяти быть не должно. Если экземпляров много, я обычно в середину тыкаю после сортировки по размеру. Либо по размеру можно выбрать крупные, если их явно не должно быть в памяти. Потом открываете один какаой экземпляр, вверху будут всего его поля. А внизу все, кто на него ссылается. Вот в нижней секции есть полезная опция - правой клик - Nearest GC Roots - по нему находите что ваше массивы связаны с JDBC драйвером и лежат в его кешах, потому что вы Statement-ы или где-то не закрываете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 15:19 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
ivanraРазглядывать масивы в Visual VM - пустое занятие Та ладно. Для небольших куч Visual VM - вполне норм. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 15:22 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
JDBC используется? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 16:31 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
Leonid Kudryavtsev, нет, есть считывание файла с диска и отправка его по сети. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 17:03 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
Dymytryнет, есть считывание файла с диска и отправка его по сети. Считывания куда? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 17:25 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
Вот тут собственно кратко и доступно http://visualvm.java.net/heapdump.html Если дамп не большой, можете выложить его, я посмотрю. Или картинки сделайте аналогичные - приаттачте к форуму. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 17:27 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
DymytryДопустим, в анализаторе написано что массивы char[] занимает 40% памяти. Это поля java.lang.String. И цифра 40% - вполне себе нормальная цифра. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 17:28 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
да, похоже на то. 1. Пишет сейчас: Instances Size char[] 37428 3000000 String 37210 1000000 Ну да, похоже все это строки. Похоже что размер классов указывается без размеров вложенных объектов. Но почему такая разница между char[] и String ? По идее ссылка на String должна быть небольшой по размеру, а char[] должен содержать в себе ссылку и все буквы и должен быть больше. То есть получается так: размер ссылки на строку 40 байт, размер ссылки на char[] + содержимое = 80 байт. Получается полностью объект Строка занимает 120 байт как минимум, что ли? Из которых большая часть - ссылка, а не буковки. 2. скажите, может ли быть ситуация когда утечки памяти нет, GC все убирает, но генерация мусора слишком велика и система не справляется - становится слишком медленной или OutOfMemory? Я просто так хочу найти источники этих строк потому, что мне кажется приложение в определенный момент не справляется из-за слишком большого количества мусорных объектов. Спасибо за ссылки, пойду почитаю, или может Eclipse поставлю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 19:50 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
BlazkowiczDymytryнет, есть считывание файла с диска и отправка его по сети. Считывания куда? Файл считывается в память и отправляется по сети на сервер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 19:51 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
DymytryНу да, похоже все это строки. Похоже что размер классов указывается без размеров вложенных объектов. Но почему такая разница между char[] и String ? По идее ссылка на String должна быть небольшой по размеру, а char[] должен содержать в себе ссылку и все буквы и должен быть больше. Object занимает от 8 до 16 байт в зависимости от версии JVM. Помимо строк char[] интенсивно выделяют StringBuffer, StringBuilder и реализации *Reader-ов, *Writer-ов. И не забывай что строки в Unicode. Твои расчётные формулы про 120 байт скорее всего не верны. Их надо пересчитать с учётом того не все char[] обязательно стоят в контейнере String. скажите, может ли быть ситуация когда утечки памяти нет, GC все убирает, но генерация мусора слишком велика и система не справляется - становится слишком медленной или OutOfMemory? Это в реальности так и происходит. Мы расплачиваемся за Memory Model постоянной текучестью памяти. И часть мегафлопов уходит на постоянную уборку. По поводу крашей или перегрузок GC - думаю можно создать искусственно ситуацию когда в памяти будет много ненужных объектов но удалить их трудно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 20:47 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
Dymytryда, похоже на то. 1. Пишет сейчас: Instances Size char[] 37428 3000000 String 37210 1000000 Ну да, похоже все это строки. Похоже что размер классов указывается без размеров вложенных объектов. Но почему такая разница между char[] и String ? По идее ссылка на String должна быть небольшой по размеру, а char[] должен содержать в себе ссылку и все буквы и должен быть больше. Сложно сказать. Может там строки короткие? Но судя по тому что кол-во экземпляров совпадает, да это строки. Открыл посмотрел VisualVM - там вон есть кнопка Compute Retained Sizes - это будет размер с вложениями. DymytryТо есть получается так: размер ссылки на строку 40 байт, размер ссылки на char[] + содержимое = 80 байт. Получается полностью объект Строка занимает 120 байт как минимум, что ли? Из которых большая часть - ссылка, а не буковки. Что-то много вы посчитали. Вроде 20 байт размер строки (Java 7) Dymytry2. скажите, может ли быть ситуация когда утечки памяти нет, GC все убирает, но генерация мусора слишком велика и система не справляется - становится слишком медленной или OutOfMemory? Да, конечно, если куча заполнена так и будет. Есть отдельный параметр, которым настраивается когда должен выкинуться OutOfMemoryError - при определенном наполнении кучи и при работе GC дольше определенного времени. DymytryЯ просто так хочу найти источники этих строк потому, что мне кажется приложение в определенный момент не справляется из-за слишком большого количества мусорных объектов. Если выложите дамп, могу посмотреть и объяснить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 20:48 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
DymytryФайл считывается в память и отправляется по сети на сервер. А зачем в память? IO Stream-ы или NIO Channel transfer не используются как нужно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2014, 20:49 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, если вдаваться в подробности, то: используется Netty как оболочка для RTMP клиента. Однако в данном исполнении клиента SimpleChannelUpstreamHandler-ы хранят состояния, поэтому когда мое приложение публикует на сервер несколько потоков - для каждого создается ClientBootstrap, в каждый из которых вставляется свой новый SimpleChannelUpstreamHandler (который нужен чтобы конвертить байты в объекты RtmpMessage и обратно). Эти хэндлеры и занимают много памяти, но я пока не понимаю, можно ли использовать одну общую PipelineFactory для публикации разных потоков. 0. Одна из проблем явно в этом, пробую разобраться. 1. А вот как выглядит память в Memory Profiler: http://pasteboard.co/poU1E38.png Я просто даже не представляю, что это может быть. 2. Непонятная мне особенность VisualVM - то что оно делает GC память если получать Heap Dump. Получается, что если моя проблема в том что слишком много инстансов, но вообще они все собираемы GC, но я никогда этого не обнаружу. Потому что при нажатии на getHeapDump они все благополучно собирутся. Как в картинке из п. 1: я не могу понять что вызывает такой рост памяти, потому что в момент роста система не отвечает, а когда отвечает - поздно. OutOfMemory нет, хотя может просто не выводится... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2014, 20:04 |
|
||
|
Как понять откуда взялись массивы примитивов в Heap Dump?
|
|||
|---|---|---|---|
|
#18+
Можно попробовать настроить создании дампа на OOME http://stackoverflow.com/a/8311489 Правда, на больших кучах может работать не стабильно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.02.2014, 11:11 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38545500&tid=2127710]: |
0ms |
get settings: |
5ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
153ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
2ms |
| others: | 239ms |
| total: | 472ms |

| 0 / 0 |
