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.