Массив против Матрицы с точки зрения памяти в Java

1

Я работаю над проектом, который включает в себя эвристику, и я построил его на Java (возможно, он сделал это на C). У меня проблемы с памятью.

Мое дерево создано с узлами объектов, и каждый объект содержит массив, матрицу и три целых числа. Я уже сократил многие другие значения, чтобы попытаться сохранить больше пространства памяти, однако этого все равно недостаточно.

Итак, я думал, что я мог бы также сократить матрицу и преобразовать ее в массив. Однако весь мой проект построен на координатах, чтобы достичь определенной точки в матрице. Поэтому, прежде чем делать какие-либо изменения, я хотел бы знать, сколько (или не столько) это повлияет на использование памяти.

Изменение: массив и матрица сделаны из примитивов int.

Массив - это массив [25], а матрица - это матрица [5] [5].

Матрица представляет собой доску игры с информацией о том, пустое поле или имеет внутри нее определенный тип фрагмента (все int).

Я говорю о 16 ГБ использования ОЗУ и 25 миллионов узлов.

Я сделал этот метод, чтобы клонировать массивы:

public int[] cloneArray(int[] array){
    int i = 0;
    int[] clone = new int[array.length];
    while (i < array.length){
        clone[i] = array[i];
        i++;
    }
    return clone;
}

Аналогичные методы были сделаны, к клонированным матрицам и самим объектам.

Изменение: узнав о существовании профилировщика, я сделал чек. Вот скриншот результатов: Изображение 174551

Я думаю, что эти цифры имеют смысл, потому что в консоли вы можете увидеть почти столько узлов, которые были подсчитаны, как вы можете видеть в профилировщике, состояния (в консоли "estados" - это указатель состояния, которое в настоящее время расширяется).

Таким образом, в профилировщике мы видим почти 20-метровые состояния, которые являются сгенерированными узлами. Каждое состояние содержит 1 массив и 1 матрицу.

Мы можем видеть 138m массивы, которые делятся на 6 равно 23m. А так как матрица 5x5, то в матрице содержится 5x23m массивов, а остальные 23m - массивы.

Я имею в виду? Является ли это толкование точным?

Вот ссылка на Dropbox, поэтому вы можете проверить изображение с полным разрешением: https://www.dropbox.com/s/7wxz8vch1wnrsyr/Untitled.png?dl=0

  • 1
    «Матрица» как в двумерном массиве или в произвольном объекте?
  • 0
    Да, двумерный массив.
Показать ещё 17 комментариев
Теги:
arrays
matrix

2 ответа

1
Лучший ответ

Вот несколько примеров:

int[] array = new int[25];

int[][] matrix = new int[5][5];

Пространство, занимаемое массивом:

  • 25 x 4 байтовых ints (содержимое массива)
  • 12 байтов заголовка объекта для массива
  • всего 112 байт

2D - int матрица Java фактически является массивом массивов, так что пространство, занимаемое матрицы

  • (5 x 4 байта ints + 12 байтов заголовка массива) x 5.
  • 5 x 4 байтовых ссылок + 12 байтов заголовка массива
  • всего 192 байта

(Приведенные выше предполагают 32-битные JVM и типичные размеры заголовков массивов. Это предположения для платформы, но для любой платформы JVM вы должны увязывать их с определенностью. И для JVM для Oracle HotSpot/OpenJDK с Java 6 источник код доступен для просмотра всем.)

Обратите внимание, конечно, что по мере увеличения массивов/матриц относительное сохранение для int[N^2] сравнению с int[N][N] становится меньше.

  • 0
    Быстрый вопрос, Стивен. Почему для заголовка массива есть 12 байтов? Вы можете видеть, что мои вычисления в комментариях были немного другими - у меня было 4 байта для заголовка массива. Что в заголовке кроме одного адреса?
  • 0
    @DavidWallace Смотрите этот ответ . По сути, одно слово для ссылки на класс массива, одно для флагов синхронизации и сборки мусора, одно для размера.
Показать ещё 4 комментария
1

Ваш вопрос может указывать на скрытую проблему в вашем коде, а не на "проблему с памятью". память кучи не заканчивается так быстро, вам нужно, чтобы ваш код был чрезвычайно тяжелым, чтобы добраться туда.

Тем не менее, я осмелюсь сказать, что изменение 2-мерной матрицы в массив не сильно изменило бы использование памяти. говорящий на котором - 2 наиболее распространенных способа реализации массивов больших размеров (2 и выше): 1) разрезать его на один размерный массив, затем использовать формулу:

arr[a][b].. = arr[a+b+..]

2) используйте указатели для указателей, затем вы получите массив указателей, который указывает на другой массив указателей и так далее, пока последний уровень не станет реальным объектом

это сказало (опять же, с dare), Java может уже срезать матрицу в один размерный массив за кулисами.

в любом случае, я очень подозреваю, что у вас есть утечка памяти в вашем коде, или не-конец-рекурсия, или комбинация из вышеперечисленного. попробуйте увидеть, что вы не там, прежде чем пытаться реализовать то, что вы предложили.

  • 0
    Я сомневаюсь, что у меня есть утечка памяти, потому что, когда я удалил другой массив и матрицу из конструктора, узлы, которые могут быть сгенерированы, почти удвоились.
  • 0
    «поскольку Java является языком управляемого кода, а код Oracle JVM не является открытым, мы не можем на 100% ответить о том, как java запускает память, или какие оптимизации она выполняет для кода». Это мусор. Исходный код основной JVM и GC все с открытым исходным кодом. AFAIK, единственный исходный код, который вы не можете получить, относится к «специальному материалу», для которого вам нужна платная лицензия.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню