contextDestroyed() vs addShutdownHook()

六眼飞鱼酱① 提交于 2019-11-28 08:07:25

问题


I'm currently implementing ServletContextListener and using contextDestroyed() to run cleanup tasks on my web application before it shuts down. However, I've been reading about how Runtime.addShutdownHook(Thread) can be used for the same purpose.

Is there any difference between these two methods of running cleanup before undeployment? Which is preferable for a web application, in terms of functionality, efficiency, and maintainability?


回答1:


I think the ServletContextListener is more appropriate for a web application, because you clean up resources for each and every session.

A shutdown hook is executed with the JVM is shut down. That would be when you stop your container, which is a one-time event.




回答2:


The danger with using addShutdownHook() is that you will likely get a classloader leak which will become apparent when you redeploy you app multiple times.

Because the shutdown hook's class (either a Thread subclass or a Runnable implementation in your webapp) is coming from your webapp's classloader, even after your webapp is undeployed by the container, the shutdown hook will still be registered with the system. This means the entire webapp's classloader cannot be garbage collected.

I'd definitely recommend ServletContextListener.




回答3:


Many servlet containers support operations for dynamically dropping and/or reloading WARs without shutting down the JVM process. Thus if you if you write your cleanup routine as a ServletContextListener, it could potentially be run several times during the life of the container. (For example, if you modify and reload your WAR several times while the container process is still up.)

However, if you implement your cleanup using Runtime.addShutdownHook, it will run only once: when the JVM for the container as a whole is shut down.

ServletContextListener is probably the right answer for you, as it couples your cleanup routine with the life of the web application, as opposed to the life of the container process which is hosting it.




回答4:


The leak which we are talking about will only happen if we do the hot/deployment. However, if server is restarted after every deployment change than hook should work fine without memory leak. Also, one more factor governing leak is type of resource cleaning you are trying to control via listener/hook.




回答5:


Why not do both? While ServletContextListener is more appropriate for a webapp, I find that during development the server is often stopped abruptly and then contextDestroyed() is never called, so you can have both mechanisms in place to ensure there is always a graceful shutdown:

Implement a ServletContextListener where contextInitialized calls addShutdownHook() and contextDestroyed calls removeShutdownHook(). The hook and contextDestroyed can both delegate to some internal method to actually do the cleanup.

This way, if the listener is invoked properly then the hook gets added and removed (but not invoked) and there is no leak, but if the server dies without the context being destroyed, the shutdown hook cleans things up.



来源:https://stackoverflow.com/questions/6950396/contextdestroyed-vs-addshutdownhook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!