6

So I'm currently working on a program that needs to be able to deal with a large amount of data stored in arrays and it needs a method to clear out everything in the array. For the below example, would this be a bad thing to do memory wise? I know the garbage collector would eventually clean it up for you but is there a reason why another method (e.g. a for loop and setting each value within to null) might be better than this?

Object[] objArray = new Object[n];
/*Do some stuff with objArray*/
objArray = new Object[n]

Otherwise, doing this will allow this operation to run in O(1) time vs a for loop which would take O(n).

Yuxie
  • 137
  • 1
  • 10
  • 3
    No its not. This should work perfectly and previous object will get garbage collected. – Lokesh Aug 22 '18 at 13:11
  • Question is whether you have other references to the original array. Assigning will not clear it - it will just remove one reference to it. – RealSkeptic Aug 22 '18 at 13:13
  • What are you trying to do? Do you want to actually reset the array for your code logic, or are you trying to "help the gc do its job"? – Alex M Aug 22 '18 at 13:21
  • 2
    One thing for sure - allocating an _n_ sized array is O(n), not O(1), even if it's done in native code. The Java spec always requires the array to be cleared. – RealSkeptic Aug 22 '18 at 13:30
  • I'm trying to keep both memory usage and time complexity as low as possible. Since a true clear will take O(n) time, which is problematic for a large set of data, I thought the next best option would be to help the gc. Edit: Just saw @RealSkeptic's answer and I'll be honest and say I did forget that allocating an empty array of size n takes O(n) too. – Yuxie Aug 22 '18 at 13:30
  • Will you reuse (refill) the array once it is cleared? – Alex M Aug 22 '18 at 13:39
  • Yes I will. In which case, it would be much better to simply loop through and set everything to null right? Since that would save the gc from having to clean it up, saving memory temporarily which would've had to be cleaned up otherwise. – Yuxie Aug 22 '18 at 13:45

6 Answers6

5

It is bad practice.

Firstly, assigning a new array to the variable doesn’t actually “clear” anything out (more on this below).

This is best practice:

objArray = null;

which makes the original array unreachable and therefore it will be (eventually) garbage collected.

It also avoids an unnecessary allocation of memory creating the empty array you used to replace the old one.

However, neither option “clears” out the original array, which may pose an, albeit small, security exposure. Until garbage collected, the contents of the array may be divinable if the memory contents are dumped etc.

The truly clear the array:

Arrays.fill(objArray, null);
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 3
    Assigning a new array has the same effect as assigning null. The old array no longer is referenced and will be GC'ed. – Steve11235 Aug 22 '18 at 13:42
  • @Steve It's the same effect of no longer referencing the array, however it's not the same because a useless array is wastefully created. – Bohemian Aug 22 '18 at 17:05
  • 1
    I'm pretty sure he intends to continue using the array. He just wants it to be "clean." – Steve11235 Aug 22 '18 at 17:15
1

No, it is not bad practice. However, nulling all indices of the array will very likely be faster (technically, this is what is called an implementation detail; but feel free to benchmark this on your specific system), because the extra step of allocating new memory is not needed. However, be advised to not fall victim to what is known as premature optimization, as it can cause you to waste time if you later find you need to make large changes. Also, mind that since you will keep using the existing array object, any other parts of your code that reference it will then also see the changes to it.

Zyl
  • 2,690
  • 2
  • 22
  • 27
  • 1
    "will be faster" is quite a bold claim – khelwood Aug 22 '18 at 13:14
  • 1
    Not sure if I agree with that. Requesting a "blob" of memory happens on the native site, and *could* be faster compared to having a pointer go in a loop putting nulls somewhere. But it is an interesting point. – GhostCat Aug 22 '18 at 13:25
  • I think you missed the point that OP will not be using the array again. If I read his comment correctly. – Jan Larsen Aug 22 '18 at 13:37
0

Technically, it really shouldn't matter.

It is more about readability, and communication of intent.

You see, nowadays you strive to make your objects immutable. If things can't be changed, you avoid all sorts of multi threading issues. So updating a reference to point to a new array isn't exactly in line with that.

The other point worth mentioning: if you really want to clear arrays (at least for primitive types), you better iterate the array and reset all of its slot. ( obviously that is not possible for arrays of reference types )

GhostCat
  • 137,827
  • 25
  • 176
  • 248
0

It's totally fine, since you are using 'primitive' array, instead of any Collection. You may feel insecure about memory allocation from the previous array, but don't worry the GC will clean that up for you. But when using the Collections API, you rather call:

yourCollection.clear()
0

Another approach, as used by ByteBuffer, is to keep the original array, leave its contents alone, and overwrite from the beginning. When using the array, use the index of the last element updated to avoid the remainder of the array. "Clearing" the array doesn't really gain anything, unless whatever is processing the array is looking for some specific value to indicate the end of content.

Steve11235
  • 2,849
  • 1
  • 17
  • 18
0

Typical Java users should not worry about memory management unless security or performance are explicit bottlenecks. See related questions.

If you actually need to have a way to "erase" the array for your logic (i.e mark the array as reset), and since you intend on reusing the array later, you can

  • use a boolean to mark the array as "unusable" until it has been filled again (better solution if the objects inside the array do not consume too much memory)

  • fill it with null rather than assigning null to it to avoid multiple array allocations (especially if n is large) in the long run: Arrays.fill(objArray, null);.

Alex M
  • 885
  • 9
  • 12