0

I am working on a Processing program for Brownian motion tracking.

I have an ArrayList blobs and ArrayList tomerge. The first one is a list of particles which I track and the second one is a list of particles which I want to merge.

Every particle is a Blob class object. Blob object countains ArrayList of Vectors called lespoints and int id in its data.

Since I need to merge a few particles in one, I need to destroy some Blob objects, but Java doesn't have any destructors and I don't want to use finalise(). Will this work like merge + destruction?

 public void delete(Blob a)
 {
   a = null;
 }

   void merge(ArrayList<Blob> tomerge)
   {

    int i = 0;
    int j = 0;

   while (i <= tomerge.size())
   {
     Blob k = new Blob();
       k = tomerge.get(i);
     while (j <= tomerge.get(i).siz()) {
       Vector g = k.lespoints.get(j);
      lespoints.add(g);
      j++;
     }
     if (i > 0)
     {
       delete(tomerge.get(i));
     }
     i++;
   }
   }
Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
Fulmenius
  • 5
  • 3

2 Answers2

4

You don't need to manually do anything. Just make sure you don't have any references to the variables you want to go away, and Java will handle the rest.

For example:

String x = "test";
x = null;

At this point, the value "test" can be garbage collected because nothing points to it.

Compare that to this:

String x = "test";
ArrayList<String> list = new ArrayList<>();
list.add(x);
x = null;

At this point, the value "test" cannot be garabage collected, because the ArrayList still points to it.

But if you did this:

list.remove("test");

Then it could be garbage collected.

So basically, all you need to do is remove the element from your ArrayList and Java will take care of the rest. Note that you probably don't want to do this in your current loop, as removing elements while you iterate over a list can cause you to skip over elements.

Instead, you probably want to use an iterator or just loop backwards over your ArrayList.

Shameless self-promotion: here is a tutorial on ArrayLists, including removing elements from them.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • +1 We can disregard for the example that String literals will be interned and in none of these instances "test" would actually be GCed – Hangman4358 Jun 12 '18 at 23:12
  • I'm thinking about downvoting this. You shouldn't do `list.remove("test")` while you're iterating through it with a numeric index, because you'll end up skipping values. It would be better to use an iterator, and remove values via the iterator. Or you can just set them to null, if you don't mind leaving gaps in your list. – Dawood ibn Kareem Jun 12 '18 at 23:21
  • @DawoodibnKareem Downvote if you want, but please note that all of the code in my answer is a standalone example. I'm not doing any iterating in any of my code. – Kevin Workman Jun 12 '18 at 23:30
  • @DawoodibnKareem Actually I just edited my answer to mention removing the item from the ArrayList while iterating over it. – Kevin Workman Jun 12 '18 at 23:33
  • What a shame that your blog post doesn't mention using an iterator. I'll post my own answer if I have time later. – Dawood ibn Kareem Jun 12 '18 at 23:36
  • 1
    @DawoodibnKareem Please note that this is a [tag:processing] question. I purposely chose not to mention Iterator. See also: [Processing != Java](https://meta.stackoverflow.com/questions/321127/processing-java). But you're more than welcome to post your own answer. – Kevin Workman Jun 12 '18 at 23:48
  • Ah well spotted. Perhaps the java tag should be removed from it, just to make it clear that Fulmenius is not asking about Java. Since it's not a Java question, I withdraw all my objections to your answer. Have an upvote. – Dawood ibn Kareem Jun 12 '18 at 23:57
  • @DawoodibnKareem Thanks! It's also worth noting that a Java Iterator would work in Processing as well. The only reason I didn't mention it is because Processing usually hides that stuff from you. But you can still get to it if you need to. – Kevin Workman Jun 13 '18 at 00:26
  • OK. Honestly, if I'd seen first up that this wasn't a Java question, I would never have commented on your answer at all. This is well outside my expertise. – Dawood ibn Kareem Jun 13 '18 at 01:00
0

There is an exact reason why your code example won't work.

public void delete(Blob a)
{
    a = null;
}

Blob b = new Blob();
delete(b);

In this code example, the reference which is set to null is a, not b.

You are not deleting the Blob object, you are setting the reference to null.

When the delete() method is called, there exists 2 references to the Blob.

One reference is b, which is in the calling code.

The other reference is a, which is in the called code.

a is set to null, and then the method exits. But the b reference continues to exist throughout. Therefore the Blob will never be garbage-collected.

To achieve garbage-collection, you must remove all references to an object; then it gets destructed at the JVM's convenience.


The Java Collections API for removing an object during iteration works like this:

Iterator<Blob> itr = list.iterator();
while( itr.hasNext() ) {
    Blob b = itr.next();
    if( /* test condition */ ) {
        itr.remove();  // Safely removes object from List during iteration
    }
} // Object `b` goes out of scope, and so this Blob is "lost" to the the code and is going to be destroyed
Stewart
  • 17,616
  • 8
  • 52
  • 80