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