1

在 servlet 容器中,servlet 'S' 被实例化并服务了一些请求。它依赖于对象“O”,因此它在实例化“S”时创建了该对象。对“O”的唯一引用是通过“S”。

在服务了最初的几次请求后,“S”很长一段时间都没有收到任何请求。现在的问题是:'S' 会被垃圾收集,'O' 会随之而来吗?

或者换句话说,是否存在一些引用“S”的服务器对象“A”,因此无论它是否长时间服务任何请求,它都不会被垃圾收集?如果有一些这样的对象'A',那么谁指的是'A'所以'A'不是垃圾收集等等?

4

1 回答 1

2

你的问题没有完美的答案。Servlet 3.0 规范中的第 2.3.4 节指出:

servlet 容器不需要在任何特定时间段内保持加载 servlet。servlet 实例可以在 servlet 容器中保持活动状态,时间为毫秒,在 servlet 容器的生命周期内(可能是几天、几个月或几年),或者介于两者之间的任何时间。

当 servlet 容器确定应该从服务中删除一个 servlet 时,它会调用 Servlet 接口的 destroy 方法以允许 servlet 释放它正在使用的任何资源并保存任何持久状态。例如,当容器想要节省内存资源或正在关闭时,它可能会这样做。

所以它高度依赖于容器本身。有些可能会提供配置功能以在一段时间不活动后卸载 servlet(我不知道有任何功能,但从来不需要这样的功能)。

结论

在服务了最初的几次请求后,“S”很长一段时间都没有收到任何请求。现在的问题是:'S' 会被垃圾收集,'O' 会随之而来吗?

Servlet 本身的垃圾收集依赖于容器,并且应该在javax.servlet.Servlet.destroy()被调用之后进行。之后应该为 GC 标记 servlet 'S' - 包括所有引用的对象 'O'(只要这些对象没有在其他地方引用)。同样,它取决于容器的实现。

IMO,这在现实中并不重要。您应该始终认为 servlet 与容器一样长,并且停止容器通常会通过停止 JVM 来释放所有内存。

于 2012-08-08T10:15:49.763 回答