73 megabyte NullPointerException objects out of memory'ing our JVM

C

C B

On our IBM 1.4.1 JVM we sometimes get an out of memory error.
According the IBM heapdump and heaproots, it is a large
NullPointerException being thrown from a finalize(). In our
application, should we catch all exceptions in our finalize() methods
and prevent them from being thrown further? What does the
"Finalizer" thread do with the exceptions that it gets from finalize()
methods? Why does this 73megabyte null pointer happen in the first
place??

Any suggestions?


Showing objects whose type is in 'A,R', sorted by total-size.

Addr Size Root-owner Parent Total-size Name
-------------------------------------------------------------------------------
R 0x10143330 32 - - 73,254,488
java/lang/NullPointerException


<0> [73,254,488] 0x10143330 [32] java/lang/NullPointerException
<1> [73,254,456] 0x10143308 [40] array of java/lang/Object
<2> [73,254,056] 0x4043b6f8 [304] class java/lang/ref/Finalizer
<3> [73,253,488] 0x1a450358 [32] java/lang/ref/Finalizer
<4> [73,253,416] 0x1a419818 [32] java/lang/ref/Finalizer
<5> [73,253,344] 0x14bfc2e0 [32] java/lang/ref/Finalizer
<6> [73,253,080] 0x1a3cce70 [32] java/lang/ref/Finalizer
<7> [73,216,312] 0x1a3b3a80 [32] java/lang/ref/Finalizer
<8> [73,216,280] 0x1a3a9938 [32]
java/lang/ref/Finalizer
<9> [73,216,136] 0x1a3858b8 [32]
java/lang/ref/Finalizer
<10> [73,216,064] 0x1a352f00 [32]
java/lang/ref/Finalizer
<11> [73,215,992] 0x1a344b60 [32]
java/lang/ref/Finalizer
<12> [72,964,856] 0x1a344b80 [16]
java/lang/ClassLoader$Finalizer
 
J

John C. Bollinger

C said:
On our IBM 1.4.1 JVM we sometimes get an out of memory error.
According the IBM heapdump and heaproots, it is a large
NullPointerException being thrown from a finalize(). In our
application, should we catch all exceptions in our finalize() methods
and prevent them from being thrown further?

No. You should never catch an exception if you don't have some sensible
way of handling it. Occasionally that sensible way may be to ignore it,
but that is not the norm. There is nothing special about finalize()
methods in this regard.
What does the
"Finalizer" thread do with the exceptions that it gets from finalize()
methods?

From JLS (2ed) 12.6: "If an uncaught exception is thrown during the
finalization, the exception is ignored and finalization of that object
terminates." In a compliant JVM the object will be in the "finalized"
state, but there is not enough information to determine its reachability.
Why does this 73megabyte null pointer happen in the first
place??

The only way I can imagine for you to have a NullPointerException of
that size is if the detail message accounted for pretty much all of it.

<gaze at="crystal ball">
That probably means

1) that the exception is being created by user code;
2) it is using an object's toString() method in creating the detail
message; and
3) the particular toString() method(s) in question is producing
extremely large String objects.
</gaze>

Among those, (2) is usually a poor practice [in part for this and
related reasons], but (3) is a real killer across the board. If (3)
weren't causing a problem in your Finalizer thread then you would
probably find it causing problems elsewhere. Indeed, it may be the
reason that the finalizer is running at that point in the first place.
Any suggestions?

() Do not depend on finalizers to clean up your objects' state. They
are not guaranteed to ever run (although you can force the issue -- by
consuming all the available heap space, for instance), and they delay
their associated objects' being garbage collected. Finalizers have some
similarities to C++ destructors, so programmers coming to Java with C++
experience often want to use them, but the semantics of finalizers are
different. Read JLS (2ed) 12.6 for the details.

() Do not create objects with individual memory footprints in the
multi-megabyte range. If you must create such objects then don't create
very many of them.

() Corollary: do not write toString() methods that can create
multi-megabyte Strings. If you ignore that advice and write such a
toString() method then take great care with how it is used.


John Bollinger
(e-mail address removed)
 
F

Frank

C said:
On our IBM 1.4.1 JVM we sometimes get an out of memory error.
According the IBM heapdump and heaproots, it is a large
NullPointerException being thrown from a finalize(). In our
application, should we catch all exceptions in our finalize() methods
and prevent them from being thrown further? What does the
"Finalizer" thread do with the exceptions that it gets from finalize()
methods? Why does this 73megabyte null pointer happen in the first
place??

Not sure exactly what data that dump contains, but I assume
java.lang.String would have figured somewhere in the list if space was
taken up by Strings.

My guess is you're not having problems with a single huge exception, but
rather doing something recursive which is spawning off a whole lot of
them, by the looks of it in a finalizer.


- Yet another Frank ;)
 
D

David Hilsee

C B said:
On our IBM 1.4.1 JVM we sometimes get an out of memory error.
According the IBM heapdump and heaproots, it is a large
NullPointerException being thrown from a finalize(). In our
application, should we catch all exceptions in our finalize() methods
and prevent them from being thrown further? What does the
"Finalizer" thread do with the exceptions that it gets from finalize()
methods? Why does this 73megabyte null pointer happen in the first
place??

Any suggestions?


Showing objects whose type is in 'A,R', sorted by total-size.

Addr Size Root-owner Parent Total-size Name
-------------------------------------------------------------------------- -----
R 0x10143330 32 - - 73,254,488
java/lang/NullPointerException


<0> [73,254,488] 0x10143330 [32] java/lang/NullPointerException
<1> [73,254,456] 0x10143308 [40] array of java/lang/Object
<2> [73,254,056] 0x4043b6f8 [304] class java/lang/ref/Finalizer
<3> [73,253,488] 0x1a450358 [32] java/lang/ref/Finalizer
<4> [73,253,416] 0x1a419818 [32] java/lang/ref/Finalizer
<5> [73,253,344] 0x14bfc2e0 [32] java/lang/ref/Finalizer
<6> [73,253,080] 0x1a3cce70 [32] java/lang/ref/Finalizer
<7> [73,216,312] 0x1a3b3a80 [32] java/lang/ref/Finalizer
<8> [73,216,280] 0x1a3a9938 [32]
java/lang/ref/Finalizer
<9> [73,216,136] 0x1a3858b8 [32]
java/lang/ref/Finalizer
<10> [73,216,064] 0x1a352f00 [32]
java/lang/ref/Finalizer
<11> [73,215,992] 0x1a344b60 [32]
java/lang/ref/Finalizer
<12> [72,964,856] 0x1a344b80 [16]
java/lang/ClassLoader$Finalizer

If I understand the table above, the exception contains (possibly via many
levels of indirection) a reference to a 70+MB object that is an instance of
a nested class of java.lang.ClassLoader. I don't know what that large
object is, but it could be an object that is shared by many different
objects and not something that would mean that the NullPointerException, by
itself, is very large.
 

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

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top