Re: OutOfMemoryError - how to find root cause
- From: "John C. Bollinger" <jobollin@xxxxxxxxxxx>
- Date: Wed, 27 Apr 2005 10:44:10 -0500
kaeli wrote:
In article <d4lp45$lcc$1@xxxxxxxxxxxxxxxxxxxxxxxx>, jobollin@xxxxxxxxxxx enlightened us with...
There are some gatchas related to String handling that are a reasonably good generic candidate here if your application ever deals with large Strings. A problem such as this could be data-dependent, which could explain why it didn't manifest before and now has stopped manifesting -- it might have been related to what some particular client was doing with the app.
Ooh, ooh, I deal with some strings. Strings that might be small, but might also be large. And other objects that can be large.
Do you have more you can say about this issue or links?
Even if it isn't the problem, I'd like to know more about gotchas and garbage collection in general. I am self-taught in Java (among other languages and technologies), and there's always more for me to learn.
The main issue with Strings is that the char[] backing one may have (much) greater capacity than the String itself has characters. This happens when you construct a substring in any of several ways (String.substring(), StringTokenizer, probably regex captured group, maybe others). If you extract a small substring of a large string in any of these ways, you may be fooled into thinking that it uses less heap than it really does. The solution for this issue is to construct a new String with use of the String(String) constructor, passing in the substring. That causes a new, right-sized char array to be created for the new String, and it is, IMO, the only reason to ever use the String(String) constructor.
For example, I was under the impression that once a JSP was done (no threading, thread-safe set to off so it gets a new instance per request), its resources were garbage collected, including classes it calls as beans. If I'm mistaken, that would be a real problem.
You should never set JSPs to non-thread-safe or make servlets implement SingleThreadModel. (My opinion; the two amount to the same thing.) This slightly impacts memory use, because only one instance of a JSP not declared non-thread-safe will ever be maintained by the application at one time. The *reason* to not do this has little to do with memory, however, and more to do with expectations: setting a JSP to non-thread-safe has nonobvious semantics, in that it does not completely insulate the page implementation from thread safety issues. In fact, it does *absolutely nothing* to insulate a JSP from thread-safety issues related to accessing external resources (DB connections, I/O objects, etc.). When writing JSP you need to account for and deal with the fact that the code will run in a multi-threaded environment, and declaring it non-thread-safe doesn't do the job.
As for resources, it depends. I find that it helps to keep in mind that JSP is just a shortcut to Java code; if I know how JSP constructs and actions map to Java then I can predict a JSP's fine behavioral details. It is also essential to understand how a JSP container is permitted and expected to use a JSP. Here are a few, possibly relevant details:
(1) The JSP container translates JSP code into Java servlet code, and compiles it to get a Java servlet that implements the JSP's behavior.
(2) The container will maintain exactly one instance (or possibly a pool of several instances if flagged non-thread-safe) of the servlet class to reuse across many page invocations.
(3) JSP declarations (<%! ... %>) translate into class-level declarations in the servlet.
(4) Beans declared via <jsp:useBean> translate into "attributes" of the application (servletContext), session (HttpSession), request (HttpServletRequest), or page.
From those points you should recognize:
(a) If you use assign an object to a variable declared via a JSP declaration, then that object will remain reachable long after the end of processing for a particular request -- typically at least until the variable is overwritten or the application is shut down.
(b) If you assign a bean to "session" scope, it remains reachable until you remove it from the session or the session is invalidated. (You _do_ have a reasonable session timeout, right?)
(c) If you assign a bean to "application" scope, it remains reachable until you remove it or replace it, or until the application shuts down.
There are also potential issues shared with plain Java, such as being certain to close() resources when you are done with them (where applicable).
Note that we just found out that the JVM heap (in the IPlanet config) was only set to 1MB (that's the default, apparently!), so that would be a definite problem.
Surely that was the initial heap size, not the maximum. I doubt whether IPlanet itself could run with that little heap, before any applications even come into the picture. The initial heap size will have little relationship to your OutOfMemoryError, though increasing it may get you slightly faster startup of IPlanet.
-- John Bollinger jobollin@xxxxxxxxxxx .
- References:
- OutOfMemoryError - how to find root cause
- From: kaeli
- Re: OutOfMemoryError - how to find root cause
- From: Robert
- Re: OutOfMemoryError - how to find root cause
- From: kaeli
- Re: OutOfMemoryError - how to find root cause
- From: John C. Bollinger
- Re: OutOfMemoryError - how to find root cause
- From: kaeli
- OutOfMemoryError - how to find root cause
- Prev by Date: Java threads and WinLogon processes taking CPU
- Next by Date: Re: tomcat 5 and jdk 1.4
- Previous by thread: Re: OutOfMemoryError - how to find root cause
- Next by thread: Re: OutOfMemoryError - how to find root cause
- Index(es):
Relevant Pages
|