После прочтения этой старой статьи измерения потребления памяти несколькими типами объектов я был поражен, увидев, сколько памяти String
s используется в Java:
length: 0, {class java.lang.String} size = 40 bytes
length: 7, {class java.lang.String} size = 56 bytes
Хотя в статье есть несколько советов по минимизации этого, я не нашел их полностью удовлетворительными. Кажется, расточительно использовать char[]
для хранения данных. Очевидным улучшением для большинства западных языков стало бы использование byte[]
и кодировки, такой как UTF-8, поскольку вам требуется только один байт для хранения наиболее часто встречающихся символов, а не два байта.
Конечно, можно использовать String.getBytes("UTF-8")
и new String(bytes, "UTF-8")
. Даже накладные расходы самого экземпляра String исчезли бы. Но тогда вы теряете очень удобные методы, такие как equals()
, hashCode()
, length()
, ...
Насколько я могу судить, у Sun есть патент на byte[]
представление строк.
Рамки для эффективного представления строковых объектов в средах программирования Java
... Методы могут быть реализованы для создания строковых объектов Java в виде массивов однобайтовых символов, когда это уместно ...
Но мне не удалось найти API для этого патента.
Почему меня это волнует?
В большинстве случаев нет. Но я работал над приложениями с огромными кешами, содержащими множество строк, которые выиграли бы от более эффективного использования памяти.
Кто-нибудь знает такой API? Или есть другой способ сохранить небольшой объем памяти для строк, даже за счет производительности процессора или более уродливого API?
Пожалуйста, не повторяйте предложения из вышеприведенной статьи:
- собственный вариант
String.intern()
(возможно с SoftReferences
)
- хранение одного
char[]
и использование текущей реализации String.subString(.)
, чтобы избежать копирования данных (неприятно)
Обновление
Я запустил код из статьи о текущей JVM от Sun (1.6.0_10). Он дал те же результаты, что и в 2002 году.