首先,我想告诉我在发布之前检查When does a Java Thread reach the 'Die' State和Why my thread did not die?。
所有关于Java中的线程。我怀疑我的代码(服务器端)中的新插入线程是" java.lang.OutOfMemoryError:Java堆空间"的原因。错误我大约每2天就会收到一次(好像是Google的机器人来到我的SEO应用程序时)......
在使用线程之前,我曾经让我的tomcat服务器在128MB上运行而没有问题。插入线程后,我的tomcat服务器运行350 MB,需要每2天重新启动一次。
一般来说,这是我的主题模式:
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;
}
问题:是否100%确定上面的线程在"运行"完成 ?或者存在内存泄漏的风险吗?
提前谢谢你,
答案 0 :(得分:1)
是的,确保Thread
在执行后会死亡,JVM将收集所有使用的资源Thread
。
如果有n个请求,我可以看到,那么将产生n个Thread
,这会导致资源利用率过高。
在这种情况下,解决方案可以是Executor
API。你可以维护一个固定的线程池。它通过停止创建n个线程来确保资源利用率。
创建一个重用固定数量的线程的线程池 关闭共享的无界队列。在任何时候,最多nThreads线程 将是主动处理任务。如果提交了其他任务 当所有线程都处于活动状态时,它们将在队列中等待直到a 线程可用。如果任何线程由于故障期间终止而终止 在关机之前执行,如果需要,新的将取代它 执行后续任务。池中的线程将一直存在 它是明确关闭的。
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();
}
}
});
...
}
答案 1 :(得分:1)
java邮件中的默认超时是无限的。 如果您对smtp服务器有间歇性连接问题,那些线程可能会无限期地等待连接。 (这将被视为丢失的邮件)。无论如何,最好确保在代码中设置超时。
props.put("mail.smtp.connectiontimeout", "60");
props.put("mail.smtp.timeout", "120");