Appropriate way to delete NonJavaThread objects?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Appropriate way to delete NonJavaThread objects?

Liu, Xin
 Hi, Hotspot developers,

I have a question about NonJavaThread destructor. Currently, there are
some NonJavaThread subclasses. Here is a simple class hierarchy.

Thread
  NonJavaThrea
    NamedThread
      WorkerThread
      VMThread
    WatcherThread
    JfrThreadSampler
   
I found some subclasses of NonJavaThread disallow
destruction. Eg. VMThread and WatcherThread simply abort.
  // No destruction allowed
  ~VMThread() {
    guarantee(false, "VMThread deletion must fix the race with VM termination");
  }

Is it absolutely no resource leak if we skip ~Thread()? I know
Linux/FreeBSD guarantee to reclaim anything when a process is
terminated, but is it true for other platforms?

Putting aside resource leak, I don't think all NonJavaThread
subclasses necessarily have same lifecycle of JVM. Current
NonJavaThread implementation seems to inhibit from complete
destruction. eg.  JfrThreadSampler uses the following approach to
delete itself.

void JfrThreadSampler::post_run() {
  this->NonJavaThread::post_run();
  delete this;
}

I think this code is correct, but it is fragile because
NonJavaThread::post_run() nullifies Thread::clear_thread_current()
before Thread::~Thread(). "delete this" will hit the assertion of
Thread::current() at this statement.
  // osthread() can be NULL, if creation of thread failed.
  if (osthread() != NULL) os::free_thread(osthread())


Does it matter if we ignore all destructions of NonJavaThread objects?
If the answer is no, is there an appropriate way to delete them?

Thanks,
--lx



Reply | Threaded
Open this post in threaded view
|

Re: Appropriate way to delete NonJavaThread objects?

David Holmes
Hi,
On 8/04/2021 4:56 pm, Liu, Xin wrote:

>   Hi, Hotspot developers,
>
> I have a question about NonJavaThread destructor. Currently, there are
> some NonJavaThread subclasses. Here is a simple class hierarchy.
>
> Thread
>    NonJavaThrea
>      NamedThread
>        WorkerThread
>        VMThread
>      WatcherThread
>      JfrThreadSampler
>      
> I found some subclasses of NonJavaThread disallow
> destruction. Eg. VMThread and WatcherThread simply abort.
>    // No destruction allowed
>    ~VMThread() {
>      guarantee(false, "VMThread deletion must fix the race with VM termination");
>    }
>
> Is it absolutely no resource leak if we skip ~Thread()? I know
> Linux/FreeBSD guarantee to reclaim anything when a process is
> terminated, but is it true for other platforms?
>
> Putting aside resource leak, I don't think all NonJavaThread
> subclasses necessarily have same lifecycle of JVM. Current
> NonJavaThread implementation seems to inhibit from complete
> destruction. eg.  JfrThreadSampler uses the following approach to
> delete itself.
>
> void JfrThreadSampler::post_run() {
>    this->NonJavaThread::post_run();
>    delete this;
> }
>
> I think this code is correct, but it is fragile because
> NonJavaThread::post_run() nullifies Thread::clear_thread_current()
> before Thread::~Thread(). "delete this" will hit the assertion of
> Thread::current() at this statement.
>    // osthread() can be NULL, if creation of thread failed.
>    if (osthread() != NULL) os::free_thread(osthread())
>
>
> Does it matter if we ignore all destructions of NonJavaThread objects?
> If the answer is no, is there an appropriate way to delete them?

The lifecycle of nonJavaThreads is a bit of mix. But for those that live
as long as the VM there is no need to go through a termination process
in the general case, and for others there must not be a termination
process (eg. the VMThread holds the Threads_lock when the VM terminates,
to ensure the VM remains at a safepoint during termination, so that
thread cannot die as we risk hitting thread library assertions or other
undefined behaviour if a lock is held by a dead thread).

By-and-large we don't care because the process will be blown away and
all resources reclaimed (any platform that didn't ensure this would have
a lot of problems to deal with). When the VM is hosted there can be
resource leaks, but the threads themselves are only a tiny part of the
resources the VM leaks in that case.

NonJavaThreads that have a different lifecycle to the VM (a fairly
recent situation) should cleanly terminate and destroy themselves, but
you'd have to examine these on a case by case basis. And it may need
adjustments to the inherited post_run() actions as you note.

Cheers,
David

> Thanks,
> --lx
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Appropriate way to delete NonJavaThread objects?

Liu, Xin
Hi, David,

Got it. Thank you for sharing your experiences. I don't know hotspot
has to deal with thread library's constraints. Fair enough.

I don't know much about JfrThreadSampler. Leave it for future
investigation.

Thanks,
--lx