Я работаю над проектом, который включает в себя эвристику, и я построил его на 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;
}
Аналогичные методы были сделаны, к клонированным матрицам и самим объектам.
Изменение: узнав о существовании профилировщика, я сделал чек. Вот скриншот результатов:
Я думаю, что эти цифры имеют смысл, потому что в консоли вы можете увидеть почти столько узлов, которые были подсчитаны, как вы можете видеть в профилировщике, состояния (в консоли "estados" - это указатель состояния, которое в настоящее время расширяется).
Таким образом, в профилировщике мы видим почти 20-метровые состояния, которые являются сгенерированными узлами. Каждое состояние содержит 1 массив и 1 матрицу.
Мы можем видеть 138m массивы, которые делятся на 6 равно 23m. А так как матрица 5x5, то в матрице содержится 5x23m массивов, а остальные 23m - массивы.
Я имею в виду? Является ли это толкование точным?
Вот ссылка на Dropbox, поэтому вы можете проверить изображение с полным разрешением: https://www.dropbox.com/s/7wxz8vch1wnrsyr/Untitled.png?dl=0
Вот несколько примеров:
int[] array = new int[25];
int[][] matrix = new int[5][5];
Пространство, занимаемое массивом:
2D - int
матрица Java фактически является массивом массивов, так что пространство, занимаемое матрицы
(Приведенные выше предполагают 32-битные JVM и типичные размеры заголовков массивов. Это предположения для платформы, но для любой платформы JVM вы должны увязывать их с определенностью. И для JVM для Oracle HotSpot/OpenJDK с Java 6 источник код доступен для просмотра всем.)
Обратите внимание, конечно, что по мере увеличения массивов/матриц относительное сохранение для int[N^2]
сравнению с int[N][N]
становится меньше.
Ваш вопрос может указывать на скрытую проблему в вашем коде, а не на "проблему с памятью". память кучи не заканчивается так быстро, вам нужно, чтобы ваш код был чрезвычайно тяжелым, чтобы добраться туда.
Тем не менее, я осмелюсь сказать, что изменение 2-мерной матрицы в массив не сильно изменило бы использование памяти. говорящий на котором - 2 наиболее распространенных способа реализации массивов больших размеров (2 и выше): 1) разрезать его на один размерный массив, затем использовать формулу:
arr[a][b].. = arr[a+b+..]
2) используйте указатели для указателей, затем вы получите массив указателей, который указывает на другой массив указателей и так далее, пока последний уровень не станет реальным объектом
это сказало (опять же, с dare), Java может уже срезать матрицу в один размерный массив за кулисами.
в любом случае, я очень подозреваю, что у вас есть утечка памяти в вашем коде, или не-конец-рекурсия, или комбинация из вышеперечисленного. попробуйте увидеть, что вы не там, прежде чем пытаться реализовать то, что вы предложили.