0

Consider these similar pieces of code:

for (int iteration = 0; iteration<a_lot; iteration++) {
    int[] re = new int[large];
    for (int i = 0; i<large; i++)
        re[i] = computeValue();
    ...
}

and

int[] re = new int[large];
for (int iteration = 0; iteration<a_lot; iteration++) {
    for (int i = 0; i<large; i++)
        re[i] = computeValue();
    ...
}

In the first example we reallocate new space for the array in each iteration and let the garbage collector deal with freeing up the space of the array in the previous iteration, while in the second example we reuse the same array. I can imagine that in some circumstances the first algorithm causes (or contributes to) a StackOverflowException, while the downside of the second algorithm is that the array is never garbage collected in between iterations, even though it might be the case that after some point in the iteration the array isn't used anymore.

In which circumstances is it better to use which algorithm?

Tim Kuipers
  • 1,705
  • 2
  • 16
  • 26
  • Obviously the second array WILL be garbage collected eventually. It will go out of method scope at some point unless you store it at the class level. – Kon Apr 07 '14 at 14:07
  • Does this question/answer helps you? http://stackoverflow.com/questions/377763/declare-an-object-inside-or-outside-a-loop – Raul Guiu Apr 07 '14 at 14:08
  • @Kon That is true, see edit. "the array is never garbage collected *in between iterations*" – Tim Kuipers Apr 07 '14 at 14:10
  • @RaulGuiu I don't think that is the same question. My question is about array allocation, not variable declaration and its scope. – Tim Kuipers Apr 07 '14 at 14:16

2 Answers2

1

First, why do you think you'll get a StackOverflowException? The array will be stored on the heap(the reference will be on the stack). Second, GC is smart enough to clean memory in both cases. Actually as soon as the reference is not needed, Garbage Collector can recall the memory (it can recall memory, while being still in method.)

Eugene
  • 117,005
  • 15
  • 201
  • 306
  • GC doesn't occur the instant the reference isn't needed anymore; GC is a batch process of cleaning up all unneeded objects. In the second example the reference will be needed in every iteration, so I don't think memory will be cleaned. In that example the reference stays the same, but all integers contained will change. – Tim Kuipers Apr 08 '14 at 10:27
1

Unless your array is so huge that it MUST be deallocated on every iteration, I see no benefit to reallocate it every time.

  • Depending on some hyperparameters, I sometimes get Heap Space problems. I am trying to figure out if I should change procedures in my program to the kind of my first example in order to reduce the chance of such errors. Would that be a case where I **must** deallocate the arrays? – Tim Kuipers Apr 08 '14 at 10:30
  • @TimKuipers it's hard to tell, are your arrays *that* big? Can you show us an example of your relevant code may be? Also what parameters are you using when starting your app? – Eugene Apr 08 '14 at 11:00
  • I am implementing convolutional neural networks. It will be hard to show you the relevant code. It's not that the arrays are that big, but that I have a lot of them. For each image, for each neuron, in each layer I have 3-dimensional arrays of doubles. Each iteration of the whole network the 3-dimensional arrays corresponding to the (intermediate) output of each layer for each image gets recomputed. I am wondering whether it will be better to reallocate the arrays for the (intermediate) output - not the arrays for the weights of the connections between neurons in the network. – Tim Kuipers Apr 08 '14 at 11:19
  • Does your application work better (less heap space problems) if you reallocate ? –  Apr 08 '14 at 15:07