Java Thread termination in J2ObjC

127 views
Skip to first unread message

maximili...@gmail.com

unread,
May 26, 2020, 5:29:08 AM5/26/20
to j2objc-discuss
Hi all,

while converting my project by using J2ObjC 2.4, I realized following behavior by using the Instruments tool on the Mac.
Unless in Java the converted application never diposes my Threads and still shows the following "Created & Persistent" Allocations in the Instruments tool:


Here in this picture you can see that all the Threads which got started within my SWIFT demo application are getting kept as "Created & Persistent" allocations.
I created a very basic Thread example in Java and used the following converted classes in my demo application:

SimpleThread.java
package com.test.thread;

public class SimpleThread extends Thread {
   
   
private final static int NUMBER_OF_ITERATIONS = 10000;

   
public void run() {
        addSomething
();
   
}
   
   
private int addSomething() {
       
int result = 0;
       
       
for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) {
            result
+= i;
       
}
       
       
return result;
   
}
}

SimpleThreadExecutor.java
package com.test.thread;

public class SimpleThreadExecutor {
   
   
private SimpleThread simpleThread;
   
   
public void startSimpleThread() {
       
this.simpleThread = new SimpleThread();
       
this.simpleThread.start();
   
}
}

ViewController.swift
class ViewController: UIViewController {

    @IBAction func buttonClicked (sender: AnyObject) {
        let simpleThreadExecutor : ComTestThreadSimpleThreadExecutor = ComTestThreadSimpleThreadExecutor.init();
        simpleThreadExecutor.startSimpleRunnable();
    }
   
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

I already experimented with ARC and Non-ARC mode but actually both of them are resulting in the same problem.
In my understanding of the shown allocations in the instruments tool this would lead to a memory leak as Threads will never get disposed until the application ends.

Can someone please clarify how to properly use Java Threads with J2ObjC, I guess I am doing something fundamentally wrong here.

Thank you:)

Tom Ball

unread,
May 27, 2020, 12:44:01 AM5/27/20
to j2objc-discuss
It looks like you're doing everything right, but found a serious leak. Many teams have moved from managing their own threads to using something like a ThreadPoolExecutor, so they aren't seeing this. Still, it needs to be fixed.

I haven't investigated this thoroughly, but a quick read of thread start and end code suggests a possible solution. Thread.start0() is where the prthread is created and initialized, at line 433:

pthread_create(&nt->t, &attr, &start_routine, [self retain]);
The "[self retain]" is necessary so that the new thread isn't dealloc'd when the calling thread's autoreleasepool is drained. However, shouldn't start_routine() call "[self release]" before it returns NULL? Your thoughts?



--
You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/j2objc-discuss/89123e1f-01cc-48ca-b9f1-64c8c8b6c34a%40googlegroups.com.

maximili...@gmail.com

unread,
May 27, 2020, 10:35:17 AM5/27/20
to j2objc-discuss
Thanks for the fast reply:)

The usage of the ThreadPoolExecutor would be a good enough workaround for applications which are not composed out of multiple layers and hence can use one shared ThreadPoolExecutor.

About the change in the Thread implementation, I am not sure if the actual leak comes from the C-side (pthread not releasing the all the memory) or J2ObjC Thread implementation which is still pointing to the pthread.
The J2ObjC thread implemenation https://github.com/google/j2objc/blob/master/jre_emul/Classes/java/lang/Thread.java#L377 I assume would be fixed with the [self release] you suggested. On the other hand it could be that this issue is then still occuring on the C-side in case there wasn't a join() called on that thread or pthread_attr_setdetachstate(pthread_attr_t *attr,PTHREAD_CREATE_DETACHED); should be used before pthread_create https://github.com/google/j2objc/blob/master/jre_emul/Classes/java/lang/Thread.java#L432. But I am not sure if detaching the thread would break any other use case as I didn't check the code thoroughly.

I am going to check out your suggestion first tomorrow by building the project manually.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-...@googlegroups.com.

maximili...@gmail.com

unread,
Jun 2, 2020, 8:39:14 AM6/2/20
to j2objc-discuss
I now investigated a little bit further into this issue and tried out both approaches.

1. Using [self release] before returning Null in the start_routine wasn't even building on my end.
2. The usage of pthread_detached gave me the expected behavior but I am not sure if this is breaking some other use cases.

private native void start0() /*-[
    NativeThread *nt = (NativeThread *)self->nativeThread_;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    size_t stack = (size_t)self->stackSize_;
    if (stack >= PTHREAD_STACK_MIN) {
      pthread_attr_setstacksize(&attr, stack);
    }
   
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    pthread_create(&nt->t, &attr, &start_routine, [self retain]);
  ]-*/;

The above added line now creates a detached thread which releases after successful execution all allocated resources according to https://www.man7.org/linux/man-pages/man3/pthread_detach.3.html

@TomBall Can you please verify this fix?:)

Thank you and best regards

Tom Ball

unread,
Jun 7, 2020, 3:34:14 PM6/7/20
to j2objc-discuss
I applied your suggested patch, and it's ready for internal review. I filed issue #1304, which you're welcome to follow to be notified when it's fixed.

To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/j2objc-discuss/faed1c57-b6eb-4c94-97d3-410e66a5cba1%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages