Bear Bibeault wrote:
Joel Sander wrote:Interesting and informative. I'll look into filters. Thanks! Are you saying that using Java to create server content is completely antiquated? Does that mean that all modern servers use php?
No. I said using Java in a JSP is antiquated. Java itself, outside of a JSP, is alive and kicking.
Java code belongs in Java classes. It does not belong in a (modern) JSP.
Tomcat does sometimes swap the authentication tokens between sessions and no information or ideas about how to go about debugging this.
No, Tomcat doesn't. It must be something in your code.
I would start with cleaning it up as outlined earlier (removed new session check and extraneous cast). Then we can talk about how to further diagnose this.
Bear Bibeault wrote:Here's a few questions:
Why are you bothering to test whether the session is new or not? Either the session contains the token, or it doesn't. Why the extraneous check? Why isn't this in a filter rather than being cut/pasted into every page? (Or a prelude at miniumum?) Why are you using obsolete Java scriptlets in a JSP? Is this 12-year-old legacy code? If not, then you're using obsolete practices and technology from over a dozen years ago.
William Brogden wrote:Looks like the userToken variable is shared by all requests executing that JSP. Why are you surprised?
Possibly because looking at a JSP does not really give you an idea of the resulting actual servlet code - look at the .java file being created by your JSP for illumination.
William Brogden wrote:What is the CPU usage when the system freezes?
Martin Vajsar wrote:Just an idea: some connection pools cache PreparedStatement objects (for every connection in the pool) so that they can properly reuse them with the database and save parsing time. Maybe some other objects are cached for various reasons too. Is the leak proportional to the number of calls to your methods, or does it level off with growing number of calls (indicating the caches became saturated)?
This situation is probably worsened by the fact that in the updateDBObjects method you create many different versions of prepared statement, by not using bind for one of the values (line 71 in the corresponding printout). If I'm right then binding this value should greatly reduce the leak, because the cache will recognize you're creating identical statements and will reuse the cached version.
I haven't much experience with hunting memory leaks though, so please be forbearing if I'm way off the mark.
Martin Vajsar wrote:Hi Joel,
I've learned about prepared statement caching from documentation to Oracle's connection pool I'm using.
I assume memory profiler should help you to determine whether the statements are cached. Run the original version of your code with it, since it creates lots of distinct prepared statements and if they are indeed cached, they should be spotted easily.
Your modified code is almost right, you just need to specify a value for the fourth variable using ps.setInt(4, dbObjects[i].id).
You should also reconsider how you are measuring the memory usage. The amount of used memory you compute will steadily rise until GC collects objects that are no longer used, and this may not happen for a long time. That the amount of used memory steadily rises at the beginning of the execution is not necessarily a sign of memory leak. If you didn't get an OutOfMemory exception with the connection pool you're using now, you need to use a memory profiler to determine whether there really is a memory leak.
Paul Clapham wrote:So this isn't a resource leak, right? You don't run out of connections, as far as I can see. You're suggesting that memory is being leaked by that package. In which case, have you done any profiling to see what's going on?
Edit: I see Martin has been posting while I have been goofing off. His theory sounds not bad, and a profile should be able to test it quite readily.