Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
The moose likes Performance and the fly likes Java heap remaining high Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Performance
Bookmark "Java heap remaining high" Watch "Java heap remaining high" New topic
Author

Java heap remaining high

Aaron Abraham
Greenhorn

Joined: Dec 12, 2002
Posts: 3
I'm facing a problem with an application. On performing some complicated DB queries, the memory utilization shoots up, and accordingly, the heap is increased.
Once the operations are done, the memory utilizations remain at a high, and then, slowly crawls back to the normal levels (Note: this is not a typical GC 'drop'. I don't think GC is being done in this case). And the heap remains at high, and the application gets choked for memory.
Is there any reason for such behavior? Anything I can do about it?
I'm using JProbe for memory analysis.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Well, you can add some System.gc() calls to encourage GC to clean up earlier - e.g. immediately after you've finished processing the results of a query. Run your program using java -verbose:gc to get messages telling you when GC occurs and how much. (Or perhaps JProbe already tells you this; dunno.) You may or may not want to leave the System.gc() calls in the final (production) version of your program, but it's worth experimenting with now to see what happens.
Note that I often use up to three System.gc() calls in a row when I test like this, because I've found that (contrary to documentation) the gc() method doesn't always "do its best", and the second (and sometimes third) successive call actually does free up more memory. Again, you probably don't want to do this in procuction, but it's useful for testing.


"I'm not back." - Bill Harding, Twister
saumil shukla
Ranch Hand

Joined: Dec 01, 2000
Posts: 47
Aron,
Is it possible to break down the query into parts? As per "Java 2 Certification Guide" -Simon Roberts etc. page 22, when ever a new object is created, it is stored on the heap however variable containing reference to it will be stored on stack.
public void aMethod()
{
MyClass mc = new MyClass();
}
Thus here object created on the right side will be on heap and "mc" will be on the stack. It is possible that because of very complex query, some method might be getting called over and over.
Hope this will help.
Thanks,
Saumil
Aaron V Abraham
Greenhorn

Joined: Dec 12, 2002
Posts: 1
Thanks Jim, Saumil.
The query returned a huge number of result sets, that sent up the number of objects created.
We've reduced the result set size, by introducing filters in the query.
And like you suggested, Jim, we've introduced gc() calls in the query.
However, conclusive test data after the changes have not been given yet.
Guennadiy VANIN
Ranch Hand

Joined: Aug 30, 2001
Posts: 898
Originally posted by Jim Yingst:
I've found that (contrary to documentation) the gc() method doesn't always "do its best",

Jim,
what doc you refer to? According to JVM specs, JVM is not obliged to implement garbage collection, at all. It may be ignored.
Most likely you have luck using JVM implementation that implements gc()...
Originally posted by Jim Yingst:
and the second (and sometimes third) successive call actually does free up more memory.

Nobody can resist to your stubbornness... Even dummy hardware.

Originally posted by saumil shukla:
Is it possible to break down the query into parts? As per "Java 2 Certification Guide" -Simon Roberts etc. page 22, when ever a new object is created, it is stored on the heap however variable containing reference to it will be stored on stack.

Does Java have any way to force objects' storage on the stack? For ex., in C# struct's objects are stored on the stack. Once more: structure is always on the stack and correspondingly any object inside it.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
what doc you refer to? According to JVM specs, JVM is not obliged to implement garbage collection, at all. It may be ignored.
Yeah, the specs are somewhat contradictory, depending where you look. I'm looking at the API for System.gc():
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

The second sentence seems to somewhat contradict the first. The way I interpret this is, it may be legal to have a JVM that does nothing (or very little) for garbage collection. In that case, the "best effort" for that machine is nothing. However if you've made a JVM implementation that does implement garbage collection so that it actually does something, and it is in fact successful in recovering unneeded memory in many cases, then "best effort" implies that this system will actually be used to its maximum effect. If you tell a child to clean up his room, and after he says he's made his "best effort" you look and half his toys are sill on the floor, and then you repeat the instruction and he realized he should clean up the rest as well (except sometimes you have to repeat the instruction once more) - that suggests to me that the child didn't really understand what "best effort" means. Which is maybe understandable if you're dealing with a small child, but I'm thinking that Sun's programmers should be held to a slightly higher standard.
Most likely you have luck using JVM implementation that implements gc()...
I've been using Sun's standard JDKs - it's obvious from the output that GC is implemented; it just isn't as complete as I would expect. I've observed this effect for JDK 1.2 and 1.3; I don't remember if I'v seen it for 1.4.
Nobody can resist to your stubbornness... Even dummy hardware.
I will interpret that as a compliment.
Does Java have any way to force objects' storage on the stack?
Not that I know of. I seem to recall seeing that this was under consideration as a possible enhancement, even before C# was announced - but it hasn't happened yet. I agree something like this might be nice. However I think the main work Sun has done on this sort of thing is in enhancing JVMs to sometimes do this sort of thing themselves (as part of JIT compilation) - but without giving users any explicit guarantee that it will happen. I suspect in many cases though the JIT can probably do as well asa human programmer for this sort of thing - sometimes better. I may be wrong about this however.
[ January 02, 2003: Message edited by: Jim Yingst ]
Guennadiy VANIN
Ranch Hand

Joined: Aug 30, 2001
Posts: 898
Jim,
I just wanted to check your response time to post in threads where you are not the author (and so not notified by Email). Share with me your techniques, I have difficulties in finding my post-intrusions. (I tried to confine me to 2-3 forums to facilitate the search but eventually bartenders transferred my posts into 4-5 more forums.)
In second reading I lost any confidence in my previous beliefs and started (feverishly) look through JVM specs.
Let me first to cite conclusion, because in the end I have questions:

From Chapter 9, "Garbage Collecion", of Inside the Java Virtual Machine" by Bill Venner
[/b]As you program in java, you must keep in mind that it is the garbage collector that runs finalizers on objects. [/b]
Because it is generally not possible to predict exactly when unreferenced objs will be gc-ed, it is not possible to predict when obj finalizers will be run.
As mentioned in Chapter 2, "Platform Independence", you should avoid writing programs for which correctness depends upon the timely finalization of objects. For ex., if a a finalizer of unreferenced obj releases a resource that is needed again later by the program, the resource will not be made available until after the garbage collector has run the object finalizer:"

Well, it is not correct that garbage collector may not be implemented, but its implementation is useless to count on, in any way, anyway...
What I did not count is that since garbage collector behaviour is unspecified, and it runs finalizers, I understood that anything inside finalizers are inpredictable (when it happens in time)

From Introduction to Chapter 3 of JVM specs (before 3.1):
Implementation details that are not part of the Java virtual machine's specification would unnecessarily constrain the creativity of implementors. For example, the memory layout of run-time data areas, the garbage-collection algorithm used, and any internal optimization of the Java virtual machine instructions (for example, translating them into machine code) are left to the discretion of the implementor.

Might be I memorized or understood incorrectly the last phrase: if it is left, then it is not reinforced.
from 3.5.3 of JVM specs:
Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java virtual machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements.

"never" and "explicitly" together confuse me. Is it just redundancy or something deep?
from 3.5.4 of JVM specs:
The Java virtual machine has a method area that is shared among all Java virtual machine threads. The method area is analogous to the storage area for compiled code of a conventional language or analogous to the "text" segment in a UNIX process.
****************************
The method area is created on virtual machine start-up. Although the method area is logically part of the heap, simple implementations may choose not to either garbage collect or compact it. This version of the Java virtual machine specification does not mandate the location of the method area or the policies used to manage compiled code.

OK, method area is not gc-ed. Really I do not care. What I care is that I stopped understanding concepts. Like:
If method area is created on VM start-up, then when it is, supposedly, have to be gc()-ed?
...be gc()-ed by whom?
Does it mean that if an object is *not* gc()-ed by/inside JVM, it is *not* released with the death of JVM?
I go to General Intermediate to ask Cindy. See you there...
[ January 14, 2003: Message edited by: yidanneuG ninaV ]
Guennadiy VANIN
Ranch Hand

Joined: Aug 30, 2001
Posts: 898
Jimm,
I remembered that I have read it but I could not get to the book, because I have here problems with connection (so I post bypassing the post) citing through citation of citation. Here it is:

From Chapter 9, "Garbage Collecion", of Inside the Java Virtual Machine" by Bill Venner
As mentioned in earlier chapters, the Java virtual machine specification does not require any particular garbage collection technique. It doesn't even require garbage collection at all. But until infinite memory is invented, most Java virtual machine implementations will likely come with garbage-collected heaps.

[ January 14, 2003: Message edited by: yidanneuG ninaV ]
"Fixed" the link, now it should work.
[ January 14, 2003: Message edited by: yidanneuG ninaV ]
Rod Macpherson
Greenhorn

Joined: Jan 12, 2003
Posts: 10
Originally posted by Aaron Abraham:
...the memory utilizations remain at a high, and then, slowly crawls back to the normal levels (Note: this is not a typical GC 'drop'. I don't think GC is being done in this case). And the heap remains at high, and the application gets choked for memory...

Classic GC
If there is memory available the GC need not run. What is the point in running when you have memory available? You have more memory than you need and the available heap space proves that. Forcing the GC has several diagnostic benefits but purpose is served forcing it early?
Incremental GC
Incremental GC distributes the work of collecting garbage memory. This does not ensure or even help in preventing out of memory conditions.
The solution for out of memory conditions is to cut down on the amount of reachable reference in your code. Common sense code usually does the job and you can tune it later.
Guennadiy VANIN
Ranch Hand

Joined: Aug 30, 2001
Posts: 898
I fixed earlier link,
From Chapter 9, "Garbage Collecion", of Inside the Java Virtual Machine" by Bill Venner
because it was broken (when inside quote, I really could not manage to repair)
Jim,
while I have been recently obsessed to dismantle the notion that I "make up as usual", my MAIN concern ,was that I do not believe that the phrase by Bill Venners correctly conveys the JVM specs.
I think it is misleading (me, at least).
[ January 14, 2003: Message edited by: yidanneuG ninaV ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Well, I think that Bill Vennier's quote is accurate. There are restrictions on what garbage collection can and can not do, but there's really nothing that it must do, according to the spec. If I create a JVM with no garbage collection, what part of the spec have I violated? I can implement System.gc() to do nothing and return:
Now admittedly no one will want to use this JVM since it wouln't be very good, always running out of memory. But the specs don't seem to put any requirements on me here. Unless there's a particular rule I've overlooked?
Guennadiy VANIN
Ranch Hand

Joined: Aug 30, 2001
Posts: 898
Jim,
the point that I am disappointed also is that EVEN if garbage collection is implemented but in such way, that you cannot rely on it (say when it shoots), it makes the same (almost the same)result as it was absent. Your client use application for 5 sec and in 120 garbage collector will facilitate the life.
I worked with SWING and it was nightmare. I needed to test (visualize) some detail. For this I waited a few sec that JVM re-starts up and then PC frequently freezed up. I had somewhere at JR a question a year ago why JBuilder steadily accumulates the memory size without ever releasing if it is written in Java. There was a discussion ... I cannot find
Guennadiy VANIN
Ranch Hand

Joined: Aug 30, 2001
Posts: 898
Jim,
can you help/advise me how to find that topic (where I initiated discussion on JBuilder freezing PCs). The problem that a lot of new forums did appear since, some topics have broken links (www.javaranch.com).
I cannot search by the name on the left (it is not inside text. I already discussed and was explained it in JR by Marilyn)
It was the end of 2001, might be the very beginning of 2002. I tried google.com, as well as ubb, etc. and failed to find.
For ex., what forum existed in the end of 2001 that corresponded to question about JBuilder?
Guennadiy VANIN
Ranch Hand

Joined: Aug 30, 2001
Posts: 898
Here it is - JBuilder is written in Java and doesn't release memory
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
EVEN if garbage collection is implemented but in such way, that you cannot rely on it (say when it shoots), it makes the same (almost the same)result as it was absent
Generally I think garbage collection works pretty well, in the sense that if you really need the memory and there really are objects eligible for collection, they get collected. The problem usually is that people write applications that retain references to classes they don't really need, and it's very difficult to track these down sometimes (unless you have a tool like JProbe).
In the case of JBuilder, I've heard that it's possible to make a custom class loader that is also capable of unloading classes - but evidently Borland didn't do this, as they didn't think it was important enough to justify the effort. (Or maybe they did in a later version.) Most users seem to have had no problem with the memory used by classes, but some do. I suppose it depends on (a) how many classes are in your project, (b) how often are you creating entirely new classes or changing their names, and (c) how much memory does your machine have. It's unfortunate that JBuilder doesn't (or at least didn't) manage to make all possible users happy in this area - but there are other IDE's out there after all.
Michael Borgwardt
Greenhorn

Joined: Dec 06, 2002
Posts: 9
So far, all discussion in this thread seems to have missed the main points.
First, System.gc(): Whether or not it does anything has nothing to do with whether the VM implements garbage collection. All serious VMs implement garbage collection. However, System.gc() is merely a suggestion to the VM that now would be a good time to do garbage collection. It may or may not heed the suggestion, but it will perform garbage collection when it's running out of memory.
Then, Aaron's observation about memory utilization. You have to realize that there are two levels of memory management involved: that of the VM and that of the OS. The VM takes memory from the OS when needed, up to its maximum heap size. However, it is not obliged to give the memory back to the OS after the objects that took up the memory have been garbage collected! Most VMs will keep hanging on to more memory than they need right now, because it would be a waste of time to give memory back to the OS just to request it again soon afterwards.
Wendal Park
Ranch Hand

Joined: Aug 28, 2001
Posts: 39
Just my 2 cents ....
Remember to close your PreparedStatement and either close your Connection or return your Connection object back to the ConnectionPool when done.
I have encountered cases in which most of the memory "shoot-ups" were a result of unclosed Statements/PreparedStatements/Connections.


MSc, BSc, SCJP 1.4<br /> <img src="graemlins/banghead.gif" border="0" alt="[banghead]" /> SCBCD
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Java heap remaining high