издержки JVM, как правило, составляют от 16 до 24 байт на объект (32-битный и 64-битный соответственно, хотя сжатые указатели могут сделать последний меньше). Tuple2
специализируется на Int
, что означает, что он хранит значения в полях, поэтому у вас есть 8 байтов на два целых числа по сравнению с 8 + 16 = 24 или 8 + 24 = 32 для (1,2). Если вы используете подобную неспециализированную коллекцию (или используете Tuple2 для чего-то, для чего она не специализирована, например, Char
), то вам нужны указатели на объекты, и вам могут понадобиться объекты в зависимости от они могут быть предварительно распределены (произвольные целые числа, нет; произвольные байты, да; произвольные символы, возможно). Если да, то вам просто нужен указатель, и это 8 + 16 = 24 или 16 + 24 = 40 байт; если нет, вам нужно три объекта, поэтому это 16 + 8 + 2 * (16 + 4) = 64 и 24 + 16 + 2 * (24 + 4) = 96 соответственно.
Итог: объекты используют лот * на 1009 * больше памяти, чем примитивные типы, обычно в 3-4 раза, но иногда более чем в 10 раз. Если у вас мало памяти, упакуйте в массивы как можно больше. Например:
Плохо для использования памяти:
val a = (1 to 10000).map(x => (x,x.toString.length)).toArray
Хорошо для использования памяти:
val b = ((1 to 10000).toArray, (1 to 10000).map(_.toString.length).toArray)
Если у вас не хватает памяти, вы можете написать итераторы и другие обертки, которые позволяют индексировать вещи, как если бы они были массивом кортежей, а не кортежем массивов. Это немного больно, но если у вас очень мало памяти, это может стоить того.