Как заставить Java использовать только определенный объем памяти? [Дубликат]

Имейте в виду, что независимо от сценария причина всегда одинакова в .NET:

Вы пытаетесь использовать ссылочную переменную, значение которой Nothing / null. Если для ссылочной переменной значение Nothing / null, это означает, что на самом деле оно не содержит ссылку на экземпляр любого объекта, который существует в куче.

Вы либо никогда не присваивали какую-либо переменную, никогда не создавали экземпляр значения, присвоенного переменной, или вы вручную устанавливали переменную, равную Nothing / null, или вы вызывали функцию, которая установите для этой переменной значение Nothing / null.

27
задан Error_404 11 April 2012 в 16:53
поделиться

5 ответов

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

0
ответ дан DaveFar 23 August 2018 в 19:24
поделиться

Строки проблематичны

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

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

Как только при профилировании использования ЦП в веб-приложении, которое также имело зависимость от JDBC Oracle, я обнаружил, что 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, C ++, Objective-C или любой другой язык управления ручной памятью / времени выполнения. Вы не можете решить, что находится в памяти или нет на уровне детализации, который вы ожидаете от вас.

24
ответ дан feeling unwelcome 23 August 2018 в 19:24
поделиться

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

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

enter image description here [/g1]

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

8
ответ дан Ingo Kegel 23 August 2018 в 19:24
поделиться

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

Подробнее о том, как включить: http://sysdotoutdotprint.com/technologies/java/6

2
ответ дан mel3kings 23 August 2018 в 19:24
поделиться

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

2
ответ дан Rob Tanzola 23 August 2018 в 19:24
поделиться
Другие вопросы по тегам:

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