My Tomcat 7 is reporting that there may be a memory leak in my webapp
SEVERE: The web application [/mywebapp] appears to have started a
thread named [pool-1-thread-1] but has failed to stop it. This is
very likely to create a memory leak.
I have a long running task in my webapp that gets initialized when the webapp is started.
public class MyContextListener implements ServletContextListener{
Scheduler scheduler = null;
public MyContextListener(){
scheduler = new Scheduler();
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
scheduler.stop();
}
#Override
public void contextInitialized(ServletContextEvent arg0) {
scheduler.start();
}
}
.. and my Scheduler.java
public class Scheduler {
private final ScheduledExecutorService fScheduler;
public Scheduler() {
fScheduler = Executors.newScheduledThreadPool(1);
}
public void start(){
fScheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
//Perform some task
}
}, 1, 240, TimeUnit.MINUTES);
}
public void stop(){
fScheduler.shutdownNow();
}
}
Even though I calling scheduler.stop(); when shutting down the server, its still reporting there could be a memory leak.
This app is deployed on jelastic.com and I find that once it is started, it runs well for around two days and then the tasks don't seem to be running. There is no exceptions or errors in the logs too.
Am I doing anything wrong here ? Is there really a potential memory leak ?
Calling fScheduler.shutdownNow(); is not enough:
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks.
From JavaDoc.
Instead you must explicitly wait for the tasks that are currently running:
fScheduler.shutdownNow();
fScheduler.awaitTermination(10, TimeUnit.SECONDS);
I believe you should not call the shutdown from the Listener but from the Servlet directly.
contextDestroyed() of the listener is too late for the executor service. As stated in the javadoc All servlets and filters will have been destroyed before any ServletContextListeners are notified of context destruction.
whereas overriding the servlet destroy() should be OK as according to the javadoc This method gives the servlet an opportunity to clean up any resources that are being held (for example, memory, file handles, threads...
#Override
public void destroy( ) {
fScheduler.shutdownNow();
fScheduler.awaitTermination(10, TimeUnit.SECONDS);
super.destroy( );
}
Related
I'm using Java and I want to keep a servlet continuously running in my application, but I'm not getting how to do it. My servlet has a method which gives counts of the user from a database on a daily basis as well as the total count of the users from the whole database. So I want to keep the servlet continuously running for that.
Your problem is that you misunderstand the purpose of the servlet. It's intented to act on HTTP requests, nothing more. You want just a background task which runs once on daily basis.
EJB available? Use #Schedule
If your environment happen to support EJB (i.e. a real Java EE server such as WildFly, JBoss, TomEE, Payara, GlassFish, etc), then use #Schedule instead. Here are some examples:
#Singleton
public class BackgroundJobManager {
#Schedule(hour="0", minute="0", second="0", persistent=false)
public void someDailyJob() {
// Do your job here which should run every start of day.
}
#Schedule(hour="*/1", minute="0", second="0", persistent=false)
public void someHourlyJob() {
// Do your job here which should run every hour of day.
}
#Schedule(hour="*", minute="*/15", second="0", persistent=false)
public void someQuarterlyJob() {
// Do your job here which should run every 15 minute of hour.
}
#Schedule(hour="*", minute="*", second="*/5", persistent=false)
public void someFiveSecondelyJob() {
// Do your job here which should run every 5 seconds.
}
}
Yes, that's really all. The container will automatically pickup and manage it.
EJB unavailable? Use ScheduledExecutorService
If your environment doesn't support EJB (i.e. you're not using not a real Java EE server, but a barebones servletcontainer such as Tomcat, Jetty, etc), then use ScheduledExecutorService. This can be initiated by a ServletContextListener. Here's a kickoff example:
#WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
#Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
scheduler.scheduleAtFixedRate(new SomeFiveSecondelyJob(), 0, 5, TimeUnit.SECONDS);
}
#Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
Where the job classes look like this:
public class SomeDailyJob implements Runnable {
#Override
public void run() {
// Do your daily job here.
}
}
public class SomeHourlyJob implements Runnable {
#Override
public void run() {
// Do your hourly job here.
}
}
public class SomeQuarterlyJob implements Runnable {
#Override
public void run() {
// Do your quarterly job here.
}
}
public class SomeFiveSecondelyJob implements Runnable {
#Override
public void run() {
// Do your quarterly job here.
}
}
Do not ever think about using java.util.Timer/java.lang.Thread in a Java EE / Servlet based environment
Last but not least, never directly use java.util.Timer and/or java.lang.Thread in Java EE. This is recipe for trouble. An elaborate explanation can be found in this JSF-related answer on the same question: Spawning threads in a JSF managed bean for scheduled tasks using a timer.
I would suggest using a library like quartz in order to run the task at regular intervals. What does the servlet really do ? It sends you a report ?
You can use cron4j. http://www.sauronsoftware.it/projects/cron4j/manual.php
Implement two classes and call startTask() in main.
public void startTask()
{
// Create a Runnable
Runnable task = new Runnable() {
public void run() {
while (true) {
runTask();
}
}
};
// Run the task in a background thread
Thread backgroundThread = new Thread(task);
// Terminate the running thread if the application exits
backgroundThread.setDaemon(true);
// Start the thread
backgroundThread.start();
}
public void runTask()
{
try {
// do something...
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
In a production system that may have multiple non-jee containers running. Use anot enterprise scheduler like Quartz scheduler which can be configured to use a database for task maamgememt.
I have a ExecutorService executor = Executors.newSingleThreadExecutor(); that i want to stop when the server is shutting down.
I have a class that implements ServletContextListener and it's annotated with #WebListener.
I have the two methods in that class:
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContextListener started");
}
#Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
executor.shutdown();
executor.shutdownNow();
System.out.println("ServletContextListener destroyed");
}
And I see that it prints what's in both of them when it's supposed to, but when I press the stop button once in intelij, I get:
SEVERE: The web application [] appears to have started a thread named [pool-2-thread-1] but has failed to stop it. This is very likely to create a memory leak.
Right after it printed ServletContextListener destroyed.
I need to press the stop button again to fully stop it.
Why it doesn't shutdown the ExecutorService even though it reached the executor.shutdown();? What am I doing wrong?
PS: this is the only ExecutorService I have and no other threads are made by me.
EDIT2:
The executor service is a field in a singleton class, it's initialized with the class:
private ExecutorService executor = Executors.newSingleThreadExecutor();
This is how the class is initialized (lazy initialization):
public static RoomsManager getRoomsManager(ServletContext servletContext) {
if (servletContext.getAttribute(MANAGER_GAMES_ATTRIBUTE_NAME) == null) {
servletContext.setAttribute(MANAGER_GAMES_ATTRIBUTE_NAME, new RoomsManager());
}
return (RoomsManager)servletContext.getAttribute(MANAGER_GAMES_ATTRIBUTE_NAME);
}
And is annotated like this:
#WebListener
public class RoomsManager implements ServletContextListener {
The stop button is the red square near the play and debug buttons in intelij IDEA.
The problem is that you have two different RoomsManager instances (and hence, two different executors): first is created by Tomcat, and second is created by you.
When you annotate RoomsManager with #WebListener, Tomcat automatically creates an instance of that class and subscribes it to receive servlet context create/destroy events. That instance is the one that actually stops its executor and prints ServletContextListener destroyed.
The second instance is created by you in the getRoomsManager method (by the way, that method doesn't look thread-safe). That instance is not registered with Tomcat and doesn't receive servlet context "destroy" event, so it doesn't even try to shutdown its executor.
Doing this worked:
class YourThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
return new Thread(r, "Your name");
}
}
private ExecutorService executor = Executors.newSingleThreadExecutor(new YourThreadFactory());
Because apparently, the threads of tomcat are daemons, and therefore, when they create a new thread with return new Thread(r, "Your name"); it also becomes a daemon.
But in the DefaultThreadFactory that an executor service use, I saw that it makes sure daemonity of new threads is off.
That doesn't explain why executor.shutdown(); didn't work though, but now at least it properly shuts down.
I have a thread-pool in my application which I want to shutdown only when application stops. I tried 3 ways:
1.Shutting down in context destroyed:
#Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("CALLING CONTEXT DESTROYED.");
PersistSigningExecutor.getService().shutdown();
}
2.Shutting down in destroy method of any servlet:
#Override
public void destroy() {
super.destroy();
System.out.println("SHUTTING DOWN THREAD-POOLS");
PersistSigningExecutor.getService().shutdown();
}
3.Adding shutdown hook in contextInitialised
#Override
public void contextInitialized(ServletContextEvent sce) {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
try {
System.out.println("SHUTTING DOWN THREAD-POOLS");
PersistSigningExecutor.getService().shutdown();
}
});
}
But none of them are working. I am not seeing any print statements. And also at the end I am getting log saying :
SEVERE: The web application [/app] appears to have started a thread named [pool-1-thread-1] but has failed to stop it. This is very likely to create a memory leak.
which means the thread is still not shutdown. How to shutdown this thread-pool properly when server is shutdown or application is undeployed?
make the thread demon (setDamon(boolean)), so that it will stop when jvm starts shutting down basically demon thread does not prevent JVM to shutdown.
Or else if you plan to use ExecutorService then you need to call shutdown() or shutdownNow().
Let me know if you need more help.
I'm having a problem with closing my application because some threads are still running after I close the application.
Somebody can help me with some method to stop all Threads being executed in background before killing the main thread???
[EDITED]
With my questions about javafx I have noticed that many newer developers are facing problem managing Threads. I would like to share what I have done to simplify my life about managing threads on javafx. I've created an AsyncTask class based on AsyncTask from Android that basically do the same of Android's in a humble but effective way. You can find more information about it on Github project
You have three options here - the easiest is to simply create your Threads as deamons, which means that when your main program ends all deamon threads will terminate too.
Thread thread = new Thread();
thread.setDaemon(true);
Thats easiest, but the downside is that you wont get a graceful shutdown (ie the threads will stop, you wont get a chance to peform resource management etc, which may or may not be a problem for you).
The alternative is to keep a hold on the spawned threads and when your program receives the signal to close you iterate over the threads and pass in a signal of some sort to signa that they too should terminate
volatile boolean shutdown = false;
public void shutdown() {
shutdown = true;
}
public void run() {
while(!shutdown) {
... do your work here
}
... perform any cleanup work here
(Note: ignores any exception handling for clarity)
The last option is to use the Executor framework in java.util.concurrent
ExecutorService executorService = Executors.newFixedThreadPool(10);
... assign/invoke tasks etc
... at some point later your program is told to shutdown
... shutdown in executor too
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS); // wait for 10s in this case
executorService.shutdownNow();
Better way to fix this is add the EventHandler on Close Request:
#Override
public void start(Stage primaryStage) {
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent e) {
Platform.exit();
System.exit(0);
}
});
}
Override your Application Class
//System.exit(0) This will close all timers and threads inside the Jar application...
#Override
public void stop() throws Exception {
super.stop(); //To change body of generated methods, choose Tools | Templates.
System.exit(0);
}
Executors from the java.util.concurrent package are the way to go. Explicitly:
ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactory() {
#Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
}
});
Java 8 version with fixed ScheduledExecutorService
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, r -> {
Thread thread = Executors.defaultThreadFactory().newThread(r);
thread.setDaemon(true);
return thread;
});
The method Platform.exit() belongs to the JavaFX context.
When you call Platform.exit(), the method javafx.application.Application#stop() is called before the context terminates.
Put inside the stop() method everything that needs to be executed before the JavaFX context terminates.
With the System.exit(0) method, the application terminate abruptly.
This method is not secure because if at the moment you call System.exit(0) and a Job is still running, maybe executing a write in the database,
the application will not wait the Job fihish resulting in a corrupted database.
I have an application running JavaFX with SpringBoot and a thread pool. That is how I handle it.
//...
import javafx.application.Application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
#SpringBootApplication
public class Main extends Application {
ConfigurableApplicationContext context;
ScheduledExecutorService scheduledExecutorService;
#Override
public void init() {
this.context = SpringApplication.run(getClass());
this.context.getAutowireCapableBeanFactory().autowireBean(this);
this.scheduledExecutorService = Executors.newScheduledThreadPool(10);
}
#Override
public void stop() throws Exception {
super.stop();
this.context.close();
this.scheduledExecutorService.shutdownNow();
}
// ...
}
I'm developing a web application to be deployed onto Tomcat. When Tomcat is started, I use a servlet (in web.xml) to call a Java class:
<web-app>
<display-name>Consumer</display-name>
<servlet>
<servlet-name>start</servlet-name>
<servlet-class>com.test.sample.Consumer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
My Consumer.java subscribes to a queue on an AMQP server. I achieve this by using a while (true) loop, which works fine in a standalone Java program. Itt also works in the context of the web application, but I can never stop my Tomcat server (within my NetBeans IDE), and I believe that the while loop is the culprit. Here is some code:
public class Consumer {
public Consumer()
consume();
}
private void consume()
...
while (true) {
// Await incoming messages from queue
// Process message
}
}
}
Is there a better way to handle this? Or to signal a stop to break out of the loop?
Thanks!
Updated to use ServletContextListener:
public final class ApplicationListener implements ServletContextListener {
private ScheduledExecutorService scheduler;
public ApplicationListener() {
}
#Override
public void contextDestroyed(ServletContextEvent event) {
System.out.println("***** Stopping Consumer *****");
scheduler.shutdownNow();
}
#Override
public void contextInitialized(ServletContextEvent event) {
System.out.println("***** Starting Consumer *****");
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new ScheduledConsumer(), 0, 15000, TimeUnit.MILLISECONDS);
}
public class ScheduledConsumer implements Runnable {
#Override
public void run() {
Consumer k = new Consumer();
k.consumeOnce();
}
}
}
I have some suggestions, but they require that you modify your architecture a bit in order to more nicely play with your container environment.
Servlet containers support "listeners" that can get notification of various events. Specifically, one of them is the ServletContextListener which gets notified when the context (aka. webapp) is being brought into service (via the contextInitialized method) and when it is being brought out of service (via the contextDestroyed method).
My recommendation would be to do the following:
Change your Consumer class's constructor so that it does not automatically call consume(); instead, add a public method like consumeOnce and don't use a loop at that level at all
Write a ServletContextListener that has a Consumer and a Thread reference as members as well as a volatile boolean stop flag; in contextInitialized it should create a new Consumer object, then launch a new (daemon) thread that:
Calls Consumer.consumeOnce
Calls Thread.sleep for an appropriate amount of time
Loops over the previous 2 steps until the stop flag is true
Have your ServletContextListener's contextDestroyed method set the stop flag to true and call Thread.interrupt on the running thread.
I'm sure I'm missing some exact details, but that's the general idea. When Tomcat shuts down, your code will be notified of the shutdown and you can cleanly terminate your own looping-thread. You may need to provide a way for the Consumer to abort an attempt to consume whatever it consumes (e.g. stop waiting to pull an object from an empty queue) if it doesn't abort when it gets a Thread.interrupt signal. (For instance if you use an Object.wait() in order to wait for a monitor notification, then you'll want to change that so it uses a wait with a timeout so that you won't block forever).
You have to place the code with the loop in a different thread and start the thread from your consumer.
private void consume() {
Thread x = new Thread(new Runnable() {
#Override
public void run() {
while(true) {
....
}
});
x.start();
}