Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2007

Tip: Looking for answers? Try searching our database.

finalize() allowed to be called before constructor finishes?

Thread view: 
Boris - 20 Apr 2007 23:53 GMT
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/api/java/lang/Object.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
Stefan Ram - 21 Apr 2007 00:02 GMT
>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/third_edition/html/execution.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.
Patricia Shanahan - 21 Apr 2007 00:22 GMT
> Is there any guarantee that finalize() is called only after a
> constructor finishes? I wonder as the documentation at
[quoted text clipped - 12 lines]
> 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/third_edition/html/execution.html#12.6]

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

Patricia
Boris - 21 Apr 2007 00:50 GMT
> [...]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
[quoted text clipped - 5 lines]
> 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
Patricia Shanahan - 21 Apr 2007 01:31 GMT
>> [...]I'm assuming you do not have any explicit finalize() calls in the
>> constructor.
[quoted text clipped - 34 lines]
>
> 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
Boris - 21 Apr 2007 12:24 GMT
> [...]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
Patricia Shanahan - 21 Apr 2007 16:40 GMT
>> [...]I'm sure there is something involved in the JNI work that causes
>> your
[quoted text clipped - 4 lines]
> 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?
>
[quoted text clipped - 7 lines]
> 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


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.