Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > finalize() allowed to be called before constructor finishes?

Reply
Thread Tools

finalize() allowed to be called before constructor finishes?

 
 
Boris
Guest
Posts: n/a
 
      04-20-2007
Is there any guarantee that finalize() is called only after a constructor
finishes? I wonder as the documentation at
http://java.sun.com/javase/6/docs/ap...html#finalize()
says that the "Java programming language does not guarantee which thread
will invoke the finalize method".

I ask as I have a Java class which makes two JNI calls in the constructor.
In finalize() another JNI call is made to release resources. If the class
is instantiated thousands of times in a loop without storing references I
get an exception or crash at some point as the second call in the
constructor tries to use a resource which strangely has been released
already. If I change the program and store references to make sure that
the garbage collector releases all objects only after the loop everything
works fine. I'm now trying to understand if there is a race condition as
the second JNI call in the constructor doesn't see the resource sometimes.
Any ideas?

Thanks in advance,
Boris
 
Reply With Quote
 
 
 
 
Stefan Ram
Guest
Posts: n/a
 
      04-20-2007
Boris <(E-Mail Removed)> writes:
>Is there any guarantee that finalize() is called only after a
>constructor finishes?


»A finalizer may be invoked explicitly,
just like any other method.«

JLS3, 12.6

http://java.sun.com/docs/books/jls/t...tion.html#12.6

Thus, a constructor might call »finalize()« itself before it
(i.e., the constructor) is finished (unless this is forbidden
somewhere else).

This would mean that there is no such guarantee.

 
Reply With Quote
 
 
 
 
Patricia Shanahan
Guest
Posts: n/a
 
      04-20-2007
Boris wrote:
> Is there any guarantee that finalize() is called only after a
> constructor finishes? I wonder as the documentation at
> http://java.sun.com/javase/6/docs/ap...html#finalize()
> says that the "Java programming language does not guarantee which thread
> will invoke the finalize method".
>
> I ask as I have a Java class which makes two JNI calls in the
> constructor. In finalize() another JNI call is made to release
> resources. If the class is instantiated thousands of times in a loop
> without storing references I get an exception or crash at some point as
> the second call in the constructor tries to use a resource which
> strangely has been released already. If I change the program and store
> references to make sure that the garbage collector releases all objects
> only after the loop everything works fine. I'm now trying to understand
> if there is a race condition as the second JNI call in the constructor
> doesn't see the resource sometimes. Any ideas?


I'm assuming you do not have any explicit finalize() calls in the
constructor.

According to the JLS "The completion of an object's constructor
happens-before (§17.4.5) the execution of its finalize method (in the
formal sense of happens-before)."

[12.6 Finalization of Class Instances,
http://java.sun.com/docs/books/jls/t...ion.html#12.6]

I would start looking for exactly what resource is involved, and how
actions involved in it are synchronized.

Patricia
 
Reply With Quote
 
Boris
Guest
Posts: n/a
 
      04-20-2007
On Sat, 21 Apr 2007 02:22:06 +0300, Patricia Shanahan <(E-Mail Removed)> wrote:

> [...]I'm assuming you do not have any explicit finalize() calls in the
> constructor.


Yes, no explicit finalize() call.

> According to the JLS "The completion of an object's constructor
> happens-before (§17.4.5) the execution of its finalize method (in the
> formal sense of happens-before)."
>
> [12.6 Finalization of Class Instances,
> http://java.sun.com/docs/books/jls/t...ion.html#12.6]
>
> I would start looking for exactly what resource is involved, and how
> actions involved in it are synchronized.


Hm, is it possible that because JNI is involved things might be more
complicated? I'm rather guessing here but the code is pretty simple. I'll
check everything again but to give you an idea - this code fails:

for (int i = 0; i < 100000; ++i)
{
createAndReturnObject();
}

And this code works:

Vector v = new Vector(100000);
for (int i = 0; i < 100000; ++i)
{
v.add(createAndReturnObject());
}

That's why I assume that the garbage collector causes some problems here.
I don't know if JNI functions are or can be invoked on another thread? Or
the garbage collector's thread is not properly synchronized with JNI
calls? If there are any other ideas I'd like to hear them.

Boris
 
Reply With Quote
 
Patricia Shanahan
Guest
Posts: n/a
 
      04-21-2007
Boris wrote:
> On Sat, 21 Apr 2007 02:22:06 +0300, Patricia Shanahan <(E-Mail Removed)> wrote:
>
>> [...]I'm assuming you do not have any explicit finalize() calls in the
>> constructor.

>
> Yes, no explicit finalize() call.
>
>> According to the JLS "The completion of an object's constructor
>> happens-before (§17.4.5) the execution of its finalize method (in the
>> formal sense of happens-before)."
>>
>> [12.6 Finalization of Class Instances,
>> http://java.sun.com/docs/books/jls/t...ion.html#12.6]
>>
>>
>> I would start looking for exactly what resource is involved, and how
>> actions involved in it are synchronized.

>
> Hm, is it possible that because JNI is involved things might be more
> complicated? I'm rather guessing here but the code is pretty simple.
> I'll check everything again but to give you an idea - this code fails:
>
> for (int i = 0; i < 100000; ++i)
> {
> createAndReturnObject();
> }
>
> And this code works:
>
> Vector v = new Vector(100000);
> for (int i = 0; i < 100000; ++i)
> {
> v.add(createAndReturnObject());
> }
>
> That's why I assume that the garbage collector causes some problems
> here. I don't know if JNI functions are or can be invoked on another
> thread? Or the garbage collector's thread is not properly synchronized
> with JNI calls? If there are any other ideas I'd like to hear them.
>
> Boris


I'm sure there is something involved in the JNI work that causes your
problem. In particular, do you ensure that the JNI work is completely
finished before the constructor continues executing? Is there anything
in the JNI code that is shared between objects?

Patricia
 
Reply With Quote
 
Boris
Guest
Posts: n/a
 
      04-21-2007
On Sat, 21 Apr 2007 03:31:51 +0300, Patricia Shanahan <(E-Mail Removed)> wrote:

> [...]I'm sure there is something involved in the JNI work that causes
> your
> problem. In particular, do you ensure that the JNI work is completely
> finished before the constructor continues executing? Is there anything


Is there anything I need to do to ensure it? Doesn't Java have to wait
until JNI calls return (my DLL is singe-threaded, and the JNI functions
return results which are used in the constructor)?

> in the JNI code that is shared between objects?


That's a good point. If I think about it the problem might arise from the
fact that finalize() can be invoked at any time on any thread. I think I
can rely on constructors being called one after another in a loop. And as
I learnt I can also rely on finalize() being called after the constructor
of the same object. However I can't rely on finalize() being called while
no constructor for another object is running. And as my DLL uses a
C++ container to track all resources this container might be used from two
threads at the very same time - one adding a resource, another one
removing another resource.

Thanks for your comments, Patricia! They were very helpful! I'll look go
back to code and check the details.

Boris
 
Reply With Quote
 
Patricia Shanahan
Guest
Posts: n/a
 
      04-21-2007
Boris wrote:
> On Sat, 21 Apr 2007 03:31:51 +0300, Patricia Shanahan <(E-Mail Removed)> wrote:
>
>> [...]I'm sure there is something involved in the JNI work that causes
>> your
>> problem. In particular, do you ensure that the JNI work is completely
>> finished before the constructor continues executing? Is there anything

>
> Is there anything I need to do to ensure it? Doesn't Java have to wait
> until JNI calls return (my DLL is singe-threaded, and the JNI functions
> return results which are used in the constructor)?


I was thinking about the possibility of multi-threading in the DLL.

>
>> in the JNI code that is shared between objects?

>
> That's a good point. If I think about it the problem might arise from
> the fact that finalize() can be invoked at any time on any thread. I
> think I can rely on constructors being called one after another in a
> loop. And as I learnt I can also rely on finalize() being called after
> the constructor of the same object. However I can't rely on finalize()
> being called while no constructor for another object is running. And as
> my DLL uses a C++ container to track all resources this container might
> be used from two threads at the very same time - one adding a resource,
> another one removing another resource.


That container seems like a good candidate.

Assuming a single garbage collection thread, delaying unreachability of
any of the objects until after the last construction would limit the
container to being accessed from one thread at a time, preventing the
problem.

Patricia
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Why defining a constant in a method is not allowed but usingself.class.const_set is allowed? IƱaki Baz Castillo Ruby 13 05-01-2011 06:09 PM
A constructor calling another constructor (default constructor)? Generic Usenet Account C++ 10 11-28-2007 04:12 AM
detecting constructor called before main 440gtx@email.com C++ 2 02-01-2007 07:21 AM
doing some initialization before the constructor gets called Vamsi C++ 3 07-19-2005 04:46 AM
how to pass this before supertype constructor has been called Paul J. Lucas Java 28 12-05-2003 09:23 PM



Advertisments