-4

Let's say I have code like this:

URI u;

for (int i = 0; i < somenumber; i++) {

    u = new URI(...);

}

If the loop spins for a lot of iterations, usually over 200 for me, 200 new objects get created each time, which is a major memory leak.

You would say that the solution is easy, subclass URI and implement clear(), right?

Wrong. It's declared final.

What to do? Copy over all the URI code from OpenJDK and use that?

Gala
  • 2,592
  • 3
  • 25
  • 33
  • `200 new objects get created each time,which is a major memory leak` There is no memory leak in your code. Maybe you need to understand what is memory leak. – Enzokie Dec 11 '16 at 00:37
  • What you do with your Object? How does this clear method help you? Because the URI-Class has no setter so even if you clear it you cant set new parameters. Futhermore as you said the class is marked as final. Normaly there is a reason for this. The Java-Developers don't want you to extend this class and so you shouldn't – Daniel Dec 11 '16 at 00:37
  • 200 is not a lot, and [there is no memory leak there](http://stackoverflow.com/questions/3798424/what-is-the-garbage-collector-in-java). Unless you're running in to actual observable problems and you've narrowed down the cause to this particular bit of code (I'm willing to bet you haven't), move on. Don't overcomplicate things for no reason, or you'll do more harm than good. – Jason C Dec 11 '16 at 01:30
  • This is not really a duplicate of the generic http://stackoverflow.com/questions/10272814/efficiency-of-creating-new-objects-in-a-loop question. This Q is really about how / whether to deal with the fact that URIs are immutable, and cannot be subclassed. – Stephen C Dec 11 '16 at 01:43

1 Answers1

2

If the loop spins for a lot of iterations, usually over 200 for me, 200 new objects get created each time, which is a major memory leak.

Technically, that isn't a memory leak. A memory leak (in Java) happens when the GC cannot reclaim the objects.

In your example, the URI object referenced by u becomes unreachable in the next loop iteration. That means that the object will almost immediately be eligible for collection, if the GC needed to do that. (It won't be necessary, unless you have the heap size set way too small.)

In a modern Java SE or Java EE JRE, the GC can reclaim short-lived garbage objects very efficiently. Your example code would not be problematic from a (normal) performance perspective.

You would say that the solution is easy, subclass URI and implement clear(), right? Wrong. It's declared final.

Yup. The URI class is designed to be an immutable class. If you could create subclasses, then a subclass could add a method to make the subclass mutable. That would invalidate the assumption "all URI's are immutable".

And your proposed clear() method is doing exactly that. It is making instances mutable.

What to do? Copy over all the URI code from OpenJDK and use that?

That would be one option. Others would be:

  • Start from scratch and design your own URI class.
  • Use String or StringBuffer to represent URIs, and parse them using using utility methods, regexes, or whatever.

However, beware that parsing URIs (which is most likely why you are using java.net.URI in the first place) is:

  • complicated, because the URI grammar is involved, and
  • likely to generate garbage objects unless you are clever with your implementation.

Before spend more time on optimizing this, I would advise you to use a Java profiler to figure out whether generating ~200 URI objects is really performance issue for your (complete) application.

Graham
  • 7,431
  • 18
  • 59
  • 84
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216