【问题标题】:How to force unload a loaded servlet from Memory | Tomcat如何从内存中强制卸载加载的 servlet |雄猫
【发布时间】:2017-10-31 09:16:28
【问题描述】:
我对 servlet 容器生命周期中的这种特殊情况感到好奇。假设我们为 servlet 容器分配了一些内存来加载 servlet(类)。现在在特定时间内存已满,容器必须加载新的 servlet。在这种情况下,当一个加载的容器用任何算法取出时(如果你能分享我也会很高兴),并被所需的 servlet 替换。这里到底发生了什么?是否调用了destroy方法?好奇的原因是,当被替换的 servlet 再次重新加载时,init() 方法是否会被第二次调用?
【问题讨论】:
标签:
tomcat
servlets
containers
【解决方案1】:
Servlet 不会因为内存已满而从内存中卸载。事实上,Servlet 对象通常很小并且通常没有任何成员变量,因为状态完全存储在由 servlet 处理的请求/响应对象中。通常,每个 servlet 在任何时候都只分配一个实例。
这基本上使您的其余问题无效。一个 servlet 只有在它的 web 应用程序被卸载时才会被卸载。发生这种情况时,确实会调用destroy。然而,在OutOfMemory 条件下,通常什么都不能再做(因为所有可以被垃圾收集的东西都将被收集),所以你不能依赖destroy 在没有剩余内存时被调用。但是,你已经猜到了,当没有更多内存时,init 将不会被再次调用,因为没有剩余空间来初始化更多对象。
重新部署 Web 应用程序时,会在取消部署的 servlet 上调用 destroy,并在首次使用新部署的 servlet 之前调用 init。
确定释放哪些对象的算法是垃圾收集器的算法(可配置)。但它只会收集未使用的(“垃圾”、“未引用”)对象,不是一段时间未使用的随机 Servlet。