0

I am currently dealing with a OutOfMemoryException in my Tomcat application, probably due to a problem with my connection pooling. Since my codebase is rather large it is quite hard to see if there is any point where a connection is only opened but not closed.

Is there any easy way in Eclipse to show me all methods that call the openConnection()-Method, but not the closeConnection()-Method?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
flixe
  • 626
  • 1
  • 11
  • 36
  • No. Have your connection pool code record stacktraces when opening and print out those not returned in time. I _believe_ I used p6spy for this a decade back. – Thorbjørn Ravn Andersen Mar 16 '21 at 09:23
  • 1
    Do Java searches for both, copy the results into a text file and compare the two text files with each other. For a deeper analysis of this kind of issue, consider to write an Eclipse plugin or SpotBugs detector. – howlger Mar 16 '21 at 11:26
  • @ThorbjørnRavnAndersen No? – howlger Mar 16 '21 at 11:29
  • @howgler "copy the results into a text file" and "compare the two text files with each other" does not exactly sound like what could be expected from any modern IDE but more a rather manual and tedious task, so no. – Thorbjørn Ravn Andersen Mar 16 '21 at 12:59
  • @ThorbjørnRavnAndersen No need for that. For Java developers it is super easy to write an extension in Eclipse. – howlger Mar 16 '21 at 16:16
  • @howlger Super easy sounds really nice. How long would it take an experienced Eclipse and Java programmer to do a proof-of-concept on such a plugin? – Thorbjørn Ravn Andersen Mar 16 '21 at 21:25
  • @ThorbjørnRavnAndersen Comparing two search results textually is easy and fast and not a tedious task. Eclipse supports the creation of a plugin via a dialog and the effort for such a plugin depends on how deep the analysis should be (like the holding problem this kind of problem is undecidable). As third solution you can write a SpotBugs detector that also operates on the AST. And probably there are more solutions. – howlger Mar 16 '21 at 23:20
  • @howlger So no _easy_ solution in Eclipse, no? – Thorbjørn Ravn Andersen Mar 17 '21 at 12:36
  • @ThorbjørnRavnAndersen You have been proven wrong. Why do you answer Eclipse questions when you haven't used it for years (according to your own statements)? – howlger Mar 17 '21 at 19:37
  • @howlger Answering "I need an **easy** way to do X in Eclipse" with "You can get a bit of some of the way in Eclipse and then do the rest by hand, or use another tool, or write a plugin for Eclipse" is not what I would expect most programmers having this problem would consider to be **easy**. You do. That might not be considered helpful, and it most definitively does not prove me wrong. – Thorbjørn Ravn Andersen Mar 23 '21 at 17:51
  • @ThorbjørnRavnAndersen _"You can get a bit of some of the way in Eclipse and then do the rest by hand, or use another tool, or write a plugin for Eclipse"_ is a quote you made up yourself and quite different from what I said. – howlger Mar 23 '21 at 22:03

1 Answers1

1

This is a tricky problem. Are you able to replicate this on a test system?

In the following I describe how I would approach solving your problem given the information you have provided.

First verify that this is actually the problem, by using a profiler on a system showing the problem while running. The traditional start is to use the stand alone version of the Netbeans profiler - VisualVMM (https://visualvm.github.io/) - where it is easy to see the memory usage over time, and to enable object allocation insights. I am unsure if the current version of VisualVM can tell you where a given object was allocated, but if it can then that might be the fastest way to identify your problematic code. If not then a trial version of a profiler that can, might be worth looking into.

If the profiler confirms that "calling X.openConnection() and then not calling X.closeConnection()" somewhere is the problem, but you still need to find out exactly where and tools like Findbugs - http://findbugs.sourceforge.net/ - and PMD - https://pmd.github.io/ - does not help you (a bit of effort here goes a long way), then I would suggest changing your code so that you collect the information you need.

If you are actually talking about database connections, then this is not an uncommon problem, so tools exist to help you. There is a rather old question at How to check the Database Connection leakage in Java EE application? but which has suggestions on how to approach this. It also has suggestions on how to catch this with tests.

At this point I would look into code - please consider the following non-compilable pseudocode. Write a revised subclass of X which maintains a global

var openConnections = new ArrayList<Map<X, Exception>>():

where each call to openConnection() also adds a single element with the object and a corresponding exception to a list somewhat like this:

public ...  openConnection(...) {
    openConnections.add(Map.of(this, new Exception()));
    return super.openConnection();
}

and then each call to closeConnection() removes it again.

public ... closeConnection(...) {
  // Loop over openConnections, if the current map has this as the first key, then
  // delete that entry.
  return super.closeConnection();
}

You should then at any time be able to see your open connections in the debugger, and where they were invoked from.

If you have the time I would strongly suggest that you rewrite your code to conform to the AutoCloseable interface instead as it allows you to use try-with-resources to let the compiler help you, and hints to static code analysis tools that this is what you want to do every time. See implements Closeable or implements AutoCloseable for a good starter question with answers.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
  • Eclipse Memory Analyzer is the tool to be used for an `OutOfMemoryException`. Instead of FindBugs, which seems to be dead for years, use its successor SpotBugs (as already mentioned in my comment above). If a question is a duplicate, close it as a duplicate instead of adding your own answer. – howlger Mar 21 '21 at 13:17
  • @howlger EMA is a heap analyzer which as far as I know is a completely different tool than the profiler that VisualVM is. Just having "Eclipse" in the name does not automatically mean it is the best tool for the job. Regarding the duplicate you've marked this as a duplicate of: It does 1) not answer the question using Eclipse, and 2) contains 11 year old answers. Was this really the best answer on SO? – Thorbjørn Ravn Andersen Mar 23 '21 at 17:54
  • As far as I know, it is called MAT, not EMA. Obviously, our knowledge differs on more than this point. – howlger Mar 23 '21 at 22:12