我有一台运行CentOS 5.9的专用服务器,Apache-Tomcat 5.5.36。我编写了一个JAVA Web应用程序,每分钟运行一次,从多个传感器收集数据。我使用ScheduledExecutorService来执行线程。 (每分钟一个线程用于每个传感器,并且可以有超过一百个传感器)线程的流程是
还有另一个应用程序每分钟检查一次数据库并将警报发送给用户(如有必要)。我使用jvisualVM监视应用程序,我找不到任何内存泄漏。为每个线程。应用程序工作正常但经过一段时间(24小时 - 48小时)后,应用程序停止工作。我无法找出问题所在,是服务器配置问题,线程太多还是什么?
有没有人知道可能出现什么问题,或者有没有人做过那种想法?请帮忙,谢谢
更新:包括代码
public class Scheduler {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void startProcess(int start) {
final Runnable uploader = new Runnable() {
@SuppressWarnings("rawtypes")
public void run()
{
//Select data from the database
ArrayList dataList = getData();
for(int i=0;i<dataList.size();i++)
{
String args = dataList.get(i).toString();
ExecutorThread comThread = new ExecutorThread(args...);
comThread.start();
}
}
};
scheduler.scheduleAtFixedRate(uploader, 0, 60 , TimeUnit.SECONDS);
}
}
public class ExecutorThread extends Thread {
private variables...
public CommunicationThread(args..)
{
//Initialise private variable
}
public void run()
{
//Collect data from sensor
//Update Database
}
}
答案 0 :(得分:1)
没有代码就不能说太多,但是你需要确保你的线程总是正常退出 - 不会在内存中挂起任何异常,关闭与数据库的连接等。
此外,为了监视您的应用程序,您可以每隔一段时间进行一次线程转储,以查看应用程序生成的线程数。
另一个建议是configure Tomcat to take a heap dump on OutOfMemoryError。如果这是一个问题,你将能够分析填补内存的内容
答案 1 :(得分:1)
请注意ScheduledExecutorService.schedule...
Javadoc
如果任务的任何执行遇到异常,则后续执行将被禁止。
这意味着,如果您在某个时间点遇到Exception
但未处理它,则Exception
会传播到ScheduledExecutorService
,这会导致您的任务无效。
要避免此问题,您需要确保整个 Runnable
包含在try...catch
中且Exception
已保证永远不会被处理。
您还可以扩展ScheduledExecutorService
(也在javadoc中提及)来处理未捕获的例外: -
final ScheduledExecutorService ses = new ScheduledThreadPoolExecutor(10){
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null) {
System.out.println(t);
}
}
};
此处afterExecute
方法仅System.out.println
Throwable
,但它可以执行其他操作。提醒用户,重启任务等......