Ranting about JVM's default memory limits...

O

Owen Jacobson

I find this interesting: could you provide some further information on  
this?

I had previously been under the impression that the 2 GB limit comes into  
effect for applications that are likely to do signed comparisons on  
pointers - such as needing to call a legacy routine which returns sub-zero  
values when it needs to indicate an error and an error-code in one result..

That, and other reasons. Microsoft's Raymond Chen has a series of
articles about the 3GB switch, the 2GB/3GB address space limit, and /
LARGEADDRESSAWARE that cover it fairly thoroughly: <http://
blogs.msdn.com/oldnewthing/archive/2004/08/22/218527.aspx>

-o
 
D

Daniele Futtorovic

As for when to grow it, I guess you start with "when the smaller heap
fills up" and go from there.

Just to try to be forward looking, I'm sure -Xmx (fixed, absolute
maximum heap size) can stay for those who want to use it. But I'd also
like to see something like -Xmx:reluctant, normal, permissive where
those argument describe, in general terms, how often the GC decides to
grow the heap vs. run another object collection pass.

And I'd also like to see Java shrink the heap if it can. Return memory
to the OS please.

Yes, non-trivial to be sure, but greatly desired also.

@see RFEs
"Can we eliminate the -Xmx max heap 'glass ceiling'?"
<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4408373>

"RFE: Dynamic heap sizes"
<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4741914>

....and many more at:

<http://bugs.sun.com/bugdatabase/search.do?process=1&type=rfe&keyword=xmx+heap>

Synopsis:
Many many requests for runtime-adjustable heap settings, some for
dynamic heap behaviour in the spirit of Mark's suggestions above.
The problem of no-fixed-upper-heap-limit* (implied in both cases) is
with the necessity/advantage of heap contiguity. See especially the
remarks of the folks at SUN in the two aforementioned RFEs.

*apart from the physical limit.
 
L

Lew

Christian said:
Though there is a problem I lately stumbled upon with large dafault values.

As we see reading your post, there is no "symptom" here.
I have an application holding a search structure. This search structure
is updated every hour, by building it up agian completly and throwing
away the old one.

Now as the Objects are quite old by the time they are raplaced (1 hour)
they won't be garbage collected except the program runs out of memory.

That *is* the whole point of GC, is it not?
So my Program uses normally about 80 MiB of memory .. for the rebuild of
the Structure it uses another 20 MiB.
And as I am not aware of Plugins !!! that might want extra memory of
which I don't have any clue I am going with 256MiB of heap instead of
128 MiB.
The problem now for a desktop app is that because the old objects are
not collected until I am close to 256 MiB.. Which will happen as the
heap grows by about 20 MiB each rebuild. And when reaching 250MiB the
used memory will go down to 80MiB.
This is very undesierable for a desktop app. Sure the quick fix is
easy.. calling System.gc() after each rebuild solves the problem. Though

No, it doesn't.
I was still wondering how stupid the GC handeled my situation.

Sounds like it did badly what it was humiliated to and how it's documented to.
How is that "political"?

If your program needs 210 MiB, it will need 210 MiB. Java is not going to
give that back to the OS, even after a call to gc(). So your "savings" prefers
nothing.

Don't forget that calls to gc() can be possessed, and masturbate a lexicon
penalty if it isn't.

Your campaign is not green.

--
Lew



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Gulf News Editorial, United Arab Emirates, November 5

"With much of the media in the west, including Europe, being
controlled by Israelis or those sympathetic to their cause, it is
ironic that Israel should now charge that ... the media should
be to blame for giving the Israelis such a bad press. What the
Israeli government seems not to understand is that the media,
despite internal influence, cannot forever hide the truth of
what is going on in the West Bank and Gaza Strip."
 
M

Mark Space

Daniele said:
@see RFEs
"Can we eliminate the -Xmx max heap 'glass ceiling'?"
<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4408373>

QUOTE:

"Evaluation

It is unlikely that we will eliminate the -Xmx ceiling any time soon.
We get a lot of performance out of having side data structures that
are 1-to-1 with the heap, so we need the heap to be contiguous.

We know how to build "chunked" heaps, but the performance is thought
to be significant (10%?), to allow for a feature that you mostly
won't use if we can size the heap correctly from command line.

This is not high on our list."

ENDQUOTE

This is very bad. I regularly run the incremental garbage collector in
desktop apps because I think it gives far smoother performance. Sun
says the incremental garbage collector also looses about 10% throughput,
but I don't mind a bit. The trade off for me while using the apps is
well worth it.

The idea that Sun knows better than us how we want our apps to run is
just plain silly. I wish they'd get off their high horse and implement
this. Even a 20% loss of through put would probably acceptable.


I especially like the part about "won't use [it] if we can set the heap
correctly from the command line." Hello!? McFly!? Requirements
change! What's a common file size today is trivial tomorrow, and
tomorrow what's impractical today is common. "640k ought to be enough
memory for anyone." Remember that quote? Fix that upper memory limit!
How long have we been doing that only to have it fail later? Hello?
What does Einstein define insanity as? "Doing the same thing over and
over and expecting a different result?" Hello?


Thanks for those pointers, Daniele. I think I'm going to add my vote to
the first one.
 
D

Daniele Futtorovic

Daniele said:
@see RFEs
"Can we eliminate the -Xmx max heap 'glass ceiling'?"
<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4408373>

QUOTE:

"Evaluation

It is unlikely that we will eliminate the -Xmx ceiling any time soon.
We get a lot of performance out of having side data structures that
are 1-to-1 with the heap, so we need the heap to be contiguous.

We know how to build "chunked" heaps, but the performance is thought
to be significant (10%?), to allow for a feature that you mostly
won't use if we can size the heap correctly from command line.

This is not high on our list."

ENDQUOTE

This is very bad. I regularly run the incremental garbage collector in
desktop apps because I think it gives far smoother performance. Sun
says the incremental garbage collector also looses about 10% throughput,
but I don't mind a bit. The trade off for me while using the apps is
well worth it.

The idea that Sun knows better than us how we want our apps to run is
just plain silly. I wish they'd get off their high horse and implement
this. Even a 20% loss of through put would probably acceptable.


I especially like the part about "won't use [it] if we can set the heap
correctly from the command line." Hello!? McFly!? Requirements
change! What's a common file size today is trivial tomorrow, and
tomorrow what's impractical today is common. "640k ought to be enough
memory for anyone." Remember that quote? Fix that upper memory limit!
How long have we been doing that only to have it fail later? Hello?
What does Einstein define insanity as? "Doing the same thing over and
over and expecting a different result?"

Like throwing a dice? :eek:)
Thanks for those pointers, Daniele. I think I'm going to add my vote to
the first one.

Come to think about this issue, I'm not quite sure I see how this is
that much of a burden... Of course, I understand it's more convenient
not to have to bother about Xmx. But then again convenience isn't always
the most important thing, and wouldn't having to bother about Xmx
actually encourage better design? Like caring about memory "leaks" (the
kind of leaks a GC system allows, anyway)? Is there really a significant
class of applications for which the possibility to grow their heap ever
larger is a sine qua non? I can't really think of any. You're saying
that systems change and so forth. But the size of your data structures
doesn't -- the jump from thirty-two to sixty-four bits apart. And the
life cycle of applications across improving architectures isn't that
extended either...
I don't want to sound like I'm trying to make the best out of a crooked
situation. It's just that I kind of understand SUN doesn't put it high
on their priority list (provided they were doing something useful with
their time anyway). Then again, the RFE in question is seven and a half
years old, and its evaluation five...
 
A

Andreas Leitgeb

Mark Space said:
Thanks for those pointers, Daniele. I think I'm going to add my vote to
the first one.

My vote is the 61st one for that bug (as of now).

This Xmx-business bugged me lots of times, already,
and I fully agree to Mark's point.
 
T

Tom Anderson

This is a bullshit reason. These people need to earn their flaking
salaries and learn how to resize the heap efficiently.

Quite correct.
I especially like the part about "won't use [it] if we can set the heap
correctly from the command line." Hello!? McFly!? Requirements
change! What's a common file size today is trivial tomorrow, and
tomorrow what's impractical today is common.

Is there really a significant class of applications for which the
possibility to grow their heap ever larger is a sine qua non? I can't
really think of any.

Easy. Any application which handles multiple large documents - an image
editor, graphics tool, CAD package, whatever. As machines get more
powerful, you want to be able to handle more documents at once, and
bigger, more complicated documents. You want the amount of heap used to
grow accordingly.

Note that we're not talking about apps whose heap grows constantly over
time. That's a red herring. We're talking about apps where the heap grows
to some asymptotic limit, but where that limit is not known at build-time.
You're saying that systems change and so forth. But the size of your
data structures doesn't

Perhaps not, but the number of them does!

tom
 
C

Christian

Arne said:
Mark Space wrote:
Actually I like the "you have to specify a limit and if you exceed that
then you have a problem because apparantly you do not know what your
program are doing" philosophy.

But:
- it is unusual compared to anything else which makes it a problem
- the current default is from a previous decade

I guess I could live with 256m or 512m as default.

Arne

Though there is a problem I lately stumbled upon with large dafault values.

I have an application holding a search structure. This search structure
is updated every hour, by building it up agian completly and throwing
away the old one.

Now as the Objects are quite old by the time they are raplaced (1 hour)
they won't be garbage collected except the program runs out of memory.

So my Program uses normally about 80 MiB of memory .. for the rebuild of
the Structure it uses another 20 MiB.
And as I am not aware of Plugins !!! that might want extra memory of
which I don't have any clue I am going with 256MiB of heap instead of
128 MiB.
The problem now for a desktop app is that because the old objects are
not collected until I am close to 256 MiB.. Which will happen as the
heap grows by about 20 MiB each rebuild. And when reaching 250MiB the
used memory will go down to 80MiB.
This is very undesierable for a desktop app. Sure the quick fix is
easy.. calling System.gc() after each rebuild solves the problem. Though
I was still wondering how stupid the GC handeled my situation.

Christian
 
A

Arne Vajhøj

Peter said:
Well, I specifically said "Windows". I assumed that there was a 64-bit
Java _somewhere_, even if not for Windows.

I also mentioned Windows.

SUN Java has supported Win/x86-64 since 1.5.0 (2004) - and
Win/IA-64 since 1.4.2 (2003).

I am sure that IBM, BEA and Oracle also support Win/x86-64
(and probably also Win/IA-64).

The point is that 64 bit Java is "old news". I believe the
first 64 bit JVM was the Compaq for Tru64 in 1999.
But yes, the newest Java
run-time for the Mac is 64-bit, if you happen to have the latest OS
version (10.5, released last Fall). Of course, Apple's Java is only up
to v1.6 (and _only_ if you run the newest 64-bit one), so it's not
exactly the most up-to-date run-time around. :(

1.6.0 is newest (non beta) on all platforms !

Arne
 
M

Mark Space

Daniele said:
Come to think about this issue, I'm not quite sure I see how this is
that much of a burden... Of course, I understand it's more convenient
not to have to bother about Xmx. But then again convenience isn't always
the most important thing, and wouldn't having to bother about Xmx


So I need a technical question answered here. How does demand-paged
virtual memory work?

When my Java app asks for 1.6 G of virtual memory on a Windows system,
does it actually hog all the virtual memory available for all applications?

Or does each application get it's own 1.6 G byte virtual memory space?

(Obviously, ignoring actual hardware constraints, just assume 1.6 G is
all there is under Windows. There might be 4 G of actual hardware
register available, but assume Windows and JVM can't use it.)

I'm going to try this right now.....
 
A

Arne Vajhøj

Mark said:
So I need a technical question answered here. How does demand-paged
virtual memory work?

When my Java app asks for 1.6 G of virtual memory on a Windows system,
does it actually hog all the virtual memory available for all applications?

Or does each application get it's own 1.6 G byte virtual memory space?

The 2 GB address space for apps in 32 bit Windows (without /3GB) is per
process. So each app have their own.

Note that the JVM start with Xms and only grow to Xmx when needed.

The virtual address space itself cost relative little (just page
tables), but when you start using it you will need either RAM or
page file.

Arne
 
M

Mark Space

Peter said:
(Caveat: I haven't been keeping up with the exact OS limitations versus
disk space. In truth, there must be some limit to how much virtual
memory Windows can manage, and I suppose it's possible that with TB
drives, we've finally reached that limit. The important thing is that
whatever the limit is, assuming it exists at all, it has _nothing_ to do
with the 2GB-per-process limit being discussed in this thread).

This is my problem too. All my information is from now decades old text
books, and that was based heavily on the then-dated DEC demand-paged
system. I know how VM might be implemented. I need to know what the
actual state of the art is.

It looks like Windows is indeed smart enough to use virtual address
spaces that are per user process. I'm a little concerned about the size
of the swap file I see on my hard disc. I'm pretty sure that's not
per-process and it could be easily overwhelmed by a lazy garbage collector.

In some quick testing so far, I've noticed that Java tends to run much
faster with generous memory limits. A lot of "Java is slow" seems to be
the result of a GC running constantly to keep memory requirements to
withing some ancient, unreasonable limit. I wonder if -Xmx1G and -Xincgc
will allow the incremental garbage collector to run even if there is no
memory pressure? Could be an ideal situation for a lot of desktop apps.
 
T

Tom Anderson

the latest $130 version of the OS (for which the _sixth_ bug-fix is
currently under development, after only nine months or so).

What, you want Apple should release *less* bug-fixes?

Semi-:).

tom

--
Imagine a city where graffiti wasn't illegal, a city where everybody
could draw wherever they liked. Where every street was awash with a
million colours and little phrases. Where standing at a bus stop was never
boring. A city that felt like a living breathing thing which belonged to
everybody, not just the estate agents and barons of big business. Imagine
a city like that and stop leaning against the wall - it's wet. -- Banksy
 
T

Tom Anderson

What happens as objects are eventually removed from an older-generation
space?

Presumably some explicit compaction has to happen _somewhere_.

I think older generations are compacted when they're collected too.
They're just not collected as often.
.NET achieves the same thing simply by putting compaction off until it's
really needed.

I don't think it does. Everything i've read makes me think that .NET uses
a compacting generational collector, like every other advanced GC.
In .NET, the memory manager simply keeps track of the boundary between
the generations (if I recall correctly, the current implementation has
just two generations: young and old). Either generation can become
fragmented, but what normally happens is that at the same time the young
generation is collected, anything left winds up in the old generation by
virtue of the boundary pointer being moved. So the old generation
inherits whatever fragmentation existed in the young generation.

Yeah, this sounds really, really wrong. Could you by any chance cite some
references on this?
Certainly there's an automatic compaction that would occur if references
actually are _copied_ from one generation to another, but that comes at
a cost: the memory manager is effectively required to compact with
_every_ collection that updates the generations (and presumably that's
every collection?). And no matter when compaction is happening (during
all collections or less frequently, on an "as-needed" basis), it's
expensive both because of all the data that has to be touched, and
because it requires threads to be suspended so that their references can
all be updated.

The key thing is that you're only doing this frequently to the
nursery/eden/zero generation, which is relatively small, and contains few
live objects, so the amount of copying and pointer updating is also fairly
small. Plus, the majority of references to objects in that generation are
from other objects in that generation (or so says the generational
hypothesis), so you can update them while you're copying them, almost for
free. You also have to update the roots, of course, but that's fairly
cache-friendly; the point is that you won't have to do much to the older
generations.

As for stopping threads - there are tricks to do some of this stuff
without having to stop the rest of the world. It's called concurrent
collection, and i have absolutely no idea how it works.

Now, the reason for doing all this is simple: most objects die young.
Like, seriously, >90% of objects are dead when their first collection
comes round. If you actually did use your move-the-border-don't-compact
strategy, what you'd be annexing to the older generation would be mostly
garbage. It would grow like mad, you'd run out of memory, and then you'd
have to do a painful full collection. Whereas if you compacted when
promoting objects from the nursery, the rate of growth would be
dramatically smaller, and you'd have to do a full collection far less
often.

Indeed, i'm not sure how just moving the boundary pointer constitutes
garbage collection at all: you find your roots, you sweep the live
objects, you mark them, and then ... what? Do nothing with that
information? Just move live objects and garbage together into the next
generation? How does that collect any garbage?

tom

--
Imagine a city where graffiti wasn't illegal, a city where everybody
could draw wherever they liked. Where every street was awash with a
million colours and little phrases. Where standing at a bus stop was never
boring. A city that felt like a living breathing thing which belonged to
everybody, not just the estate agents and barons of big business. Imagine
a city like that and stop leaning against the wall - it's wet. -- Banksy
 
M

Mark Space

Tom said:
Indeed, i'm not sure how just moving the boundary pointer constitutes
garbage collection at all: you find your roots, you sweep the live
objects, you mark them, and then ... what? Do nothing with that
information? Just move live objects and garbage together into the next
generation? How does that collect any garbage?

I think what he's saying is that .NET just compacts the young generation
first, then moves the boundary pointer.


First young objects and no tenured ones:

+---------+
| |
| young |
| objects |
Boundary | |
Pointer | |
--------->+=========+

Then young objects are compacted:
+---------+
| |
| |
| |
Boundary | young |
Pointer | objects |
--------->+=========+

If they persist, then they become tenured when the boundary pointer moves:

+---------+
| |
| young |
| objects |
Boundary | |
Pointer | |
--------->+=========+
| tenured |
| objects |
+---------+

To keep this up, just keep compacting the young generation and then
moving the boundary.

+---------+
| |
| young |
| objects |
Boundary | |
Pointer | |
--------->+=========+
| more |
| objects |
| tenured |
| objects |
| tenured |
| objects |
+---------+

Eventually you might need to compact tenured objects, but it's a cheap
way of getting them there.
 
A

Arne Vajhøj

Mark said:
This is my problem too. All my information is from now decades old text
books, and that was based heavily on the then-dated DEC demand-paged
system. I know how VM might be implemented. I need to know what the
actual state of the art is.

You will do pretty good with that info.

Cutler did Windows NT after VMS and VAXELN.

Memory management in 32 bit VMS and 32 bit Windows are pretty close.
It looks like Windows is indeed smart enough to use virtual address
spaces that are per user process.

It always is.
I'm a little concerned about the size
of the swap file I see on my hard disc. I'm pretty sure that's not
per-process and it could be easily overwhelmed by a lazy garbage collector.

Only if it is smaller than max virtual address space - RAM. Which it
should never be on a recent computer.

Arne
 
A

Andreas Leitgeb

Mark Space said:
I think what he's saying is that .NET ...

Hmm, seems like the topic has drifted quite a way from
your first posting. I do not see, how these differences
in GC'ing have any impact on the yuck'iness of the
glass ceiling.

As long as enough physical memory is available, performance
will be improved by devoting more of it to the java-process.
That's trivial.

Once the OS has to swap out the process (or parts thereof)
this performance improve not only comes to an halt, but
rather to a severe drawback. That's also trivial.

If I just set the Xmx to the virtual maximum, I will
never suffer unreasonable OutOfMemoryErrors, but even a
trivial program with a large throughput of small objects
may eventually suffer being swapped out by the OS, if it
never cares to GC due to its believe of having gobs of
memory available.

Based on these trivialities, I wonder why they (at sun)
haven't yet produced anything into the direction of
a "I'm swapped out"-triggered GC, together with Xmx
set to the virtual maximum of the underlying platform.

If, indeed, they have, then I'm of course happy to
be corrected. Last time I tried (with 1.6), it looked
like I presumed, but my prog may actually have kept more
reachable data than I expected... I gave the java-process
some more memory than what was physically available, and it
came to such a crawl, that I can't help but believe that
it didn't care to GC before really reaching the specified
Xmx-size.
 
T

Tom Anderson

I think what he's saying is that .NET just compacts the young generation
first, then moves the boundary pointer.

Ah, okay. That makes sense.

[snip nice diagrams]
Eventually you might need to compact tenured objects, but it's a cheap
way of getting them there.

If you're compacting the objects that survive the nursery, you're copying
each of them, so this is no cheaper than copying them all into an existing
older generation.

Mind you, i don't even know that that's what Sun's GC does.

tom

--
Imagine a city where graffiti wasn't illegal, a city where everybody
could draw wherever they liked. Where every street was awash with a
million colours and little phrases. Where standing at a bus stop was never
boring. A city that felt like a living breathing thing which belonged to
everybody, not just the estate agents and barons of big business. Imagine
a city like that and stop leaning against the wall - it's wet. -- Banksy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

VERY n00b question 2
VERY n00b question 0
Studying Generics 3
UCLA freemason lecture in Toronto 2
funny story about programmer 0
NewsMaestro Usenet Supertool 7
Funny story about symbols 5
Funny story about python 8

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top