1

First of all I would like to tell I checked When does a Java Thread reach the 'Die' State and Why my thread did not die? before posting this.

It's all about Threads in Java. I am suspecting new inserted threads in my code (server side) to be the cause of the "java.lang.OutOfMemoryError: Java heap space" error I am getting every 2 days approximately (seems it's when Google's robots come to my application for SEO)...

Before using threads, I used to have my tomcat server running on 128MB without problem. After inserting threads, my tomcat server is running on 350 MB with a need to restart it every 2 days.

Here is, in general, my threads's pattern :

public Boolean sendEmailInThread(String emailAddress, String message) throws IllegalArgumentException {

    try {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    sendEmail.sendMessage(emailAddress, message);
                } catch (AddressException e) {
                    e.printStackTrace();
                } catch (MessagingException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    } catch (Exception e) {
        e.printStackTrace(System.out);
    }
    return true;
}

QUESTIONS : Is it 100% sure that the thread above will die after every instructions in the "run" are done ? Or is there a risk of memory leaking ?

Thank you in advance,

Community
  • 1
  • 1
user3793589
  • 418
  • 3
  • 14
  • Answer: **Yes, it is 100% guaranteed**, unless `sendEmail.sendMessage` does not return. Maybe you should log the running threads periodically. See http://stackoverflow.com/questions/1323408/get-a-list-of-all-threads-currently-running-in-java – sampathsris Jul 23 '14 at 05:05
  • 2
    So why did you add threads? Is it possible that originally there was an occasional problem with calling `sendEmail.sendMessage()` sequentially? This problem will not go away just by parallelizing. – laune Jul 23 '14 at 05:15
  • Make sure to post *actual* code - that code ought not to compile. – user2864740 Jul 23 '14 at 05:18
  • @Krumia, thank you for your answer. I think you gave me a clue. Indeed my sendMessage is a a void method (I mean Public void sendMessage(String emailAddress, String message)). So maybe I should just return something instead of leaving void? – user3793589 Jul 23 '14 at 05:29
  • @laune, thank you for your answer. There is actually no sequentially issue. In this case for example, I am using thread so that I can reply to the user ("your message has been sent" for example) without having to wait for the real sending process (which takes about 7 seconds to accomplish)... – user3793589 Jul 23 '14 at 05:32
  • @user3793589: That is not what I meant. Return _type_ of `sendMessage` is irrelevant. What you should watch out for is if `sendMessage` returns execution to the `run()` method. You can confirm this by adding a `finally` clause to the `try` block and doing a logging there. – sampathsris Jul 23 '14 at 05:33
  • @user2864740, thank you for your answer. I will make sure next time. Nevertheless, it seems @ Krumia actually gave me a good clue... – user3793589 Jul 23 '14 at 05:34
  • @Krumia, Okay. So I should do something like this : try { sendEmail.sendMessage(emailAddress, message); } catch (AddressException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } FINALLY { System.out.println("Getting here..."); } to see if everything is terminating correctly with the sendMessage method ? – user3793589 Jul 23 '14 at 05:45
  • Yes. That's what I meant. – sampathsris Jul 23 '14 at 05:48
  • @Krumia, thank you. Will get back to you ASAP with this one. Regards, – user3793589 Jul 23 '14 at 05:51
  • @Krumia, Finally is definitely showing the message "Getting here...". Please advice... – user3793589 Jul 23 '14 at 08:25
  • Maybe you should try the suggestion I made previously: you should log the running threads periodically. – sampathsris Jul 23 '14 at 08:31

2 Answers2

1

Yes it is sure that Thread will die after execution and JVM will collect all the resource used Thread.

What I can see if there are n number of request then n number of Thread will be spawned, which cause over resource utilization.

In this case solution could be Executor API. you can maintain a fixed threadpool. It ensure resource utilization by stop creating n number of thread.

Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.

ExecutorService executorService = Executors.newFixedThreadPool(10); // 10 Threads
public Boolean sendEmailInThread(String emailAddress, String message) throws IllegalArgumentException {
...
executorService.execute(new Runnable() {
        @Override
        public void run() {
            try {
                sendEmail.sendMessage(emailAddress, message);
            } catch (AddressException e) {
                e.printStackTrace();
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
    });
...
}
Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
  • Thank you for your answer @subhrajyoti. Really interesting! However, what can limit me to increase the number of thread from 10 to 100 or 1000 instead ? – user3793589 Jul 23 '14 at 05:40
  • Umm... I See, if you really want log the return after execution - In that case create a `Callable` instead of `Runnable`, `ExecutorService`'s ` Future submit(Callable task)`. And `Future#get` return you after execution. [Check this example](http://www.journaldev.com/1650/java-futuretask-example-program) – Subhrajyoti Majumder Jul 23 '14 at 05:52
1

Default timeout in java mail is infinite. If you are having intermittent connection problems to smtp server, those threads may keep waiting for connection indefinitely. (This will be noticed as missing mails). In any case, it is always better to make sure that timeouts are set in your code.

props.put("mail.smtp.connectiontimeout", "60");
props.put("mail.smtp.timeout", "120");
Teddy
  • 4,009
  • 2
  • 33
  • 55