【发布时间】:2017-07-11 15:39:32
【问题描述】:
我的 Web 应用程序存在内存泄漏问题。应用程序在被少数人使用时会在大约 7 小时后耗尽内存。
这就是我的应用程序的工作方式:
- 用户登陆登录页面,登录,成功登录用户 POJO 对象添加到会话映射中,如下所示: FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("user", user);
- 在每个后续页面请求中,AuthFilter 都会检查会话映射中是否存在“用户”对象并允许进一步访问;
- 我有 SessionScoped bean (LoggedUserBean) 保存用户信息(连同特权,在登录时初始化),因为它被非常频繁地访问。 LoggedUserBean 被注入到大多数 bean 中,也可以直接从 XHTML 页面访问。
- 还有一些其他 SessionScoped bean 应该保持它们的状态。大多数 bean 都注入了 DAO 对象(@Named,默认为 @Dependent)。很少 bean 和所有 DAO 对象都注入了 DatabaseConnection 对象(@Named 与在构造函数中创建的数据源如下:
dataSource = (DataSource) new InitialContext().lookup("java:comp/env/" + "jdbc/MyResName");)。 - 用于验证动态创建的组件树的 Primefaces 对话框的 (@Named) 验证器很少:
<h:inputHidden value="true">
<f:validator binding="#{someValidator}"/>
</h:inputHidden>
实现是这样的:
@Named
public class SomeValidator extends ValidatorCommon implements Validator {
private final static Logger LOGGER = Logger.getLogger(SomeValidator.class);
@Override
public void validate(FacesContext fc, UIComponent uic, Object o) throws ValidatorException {...}
{...}
这是我的 context.xml:
<Resource auth="Container"
driverClassName="org.sqlite.JDBC"
maxTotal="1"
maxIdle="1"
minIdle="1"
maxWaitMillis="5000"
initialSize="1"
name="jdbc/MyResName"
type="javax.sql.DataSource"
removeAbandonedOnBorrow="true"
removeAbandonedTimeout="5"
logAbandoned="true"
validationQuery="SELECT 1"
url="jdbc:sqlite:path/to/db/db.db">
</Resource>
我已经使用 VisualVM 创建了堆转储,MAT 显示了这个泄漏嫌疑人 (https://i.imgur.com/wGsnyt5.png):
据我所知,RequestScoped bean 是在每次请求/访问时创建的,而 SessionScoped 是从容器中检索特定会话的(或者如果它不存在则创建)所以即使我的豆子,这一切都应该可以正常工作。
这就是我真正需要帮助的地方:如何分析这些泄漏的来源?肯定有什么东西不允许内存被释放,但是怎么找到呢?
我正在使用 Primefaces 6.0、Apache Tomcat (TomEE)/8.5.3 (7.0.1)、JDK 1.7.0_80-b15、Mojarra 2.2.6、sqlite-jdbc 3.14.2.1。
如果需要任何其他文件,请告诉我,我将编辑此帖子以添加它们。
Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>primefaces.FONT_AWESOME</param-name>
<param-value>true</param-value>
</context-param>
<resource-env-ref>
<resource-env-ref-name>jdbc/MyResName</resource-env-ref-name>
<resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
</resource-env-ref>
<!-- Welcome page -->
<welcome-file-list>
<welcome-file>pages/pub/login.xhtml</welcome-file>
</welcome-file-list>
<!-- Error pages -->
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/pages/pub/err/expired.xhtml</location>
</error-page>
<!-- Prevents comments in xhtml pages to be placed in final html and evaluated -->
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<!-- JSF mapping -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!-- Primefaces theme -->
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>cupertino</param-value>
</context-param>
<session-config>
<session-timeout>120</session-timeout>
</session-config>
<filter>
<filter-name>forceUTF8CharSet</filter-name>
<filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>forceUTF8CharSet</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
<mime-mapping>
<extension>ttf</extension>
<mime-type>application/font-sfnt</mime-type>
</mime-mapping>
<mime-mapping>
<extension>woff</extension>
<mime-type>application/font-woff</mime-type>
</mime-mapping>
<mime-mapping>
<extension>woff2</extension>
<mime-type>application/font-woff2</mime-type>
</mime-mapping>
<mime-mapping>
<extension>eot</extension>
<mime-type>application/vnd.ms-fontobject</mime-type>
</mime-mapping>
<mime-mapping>
<extension>eot?#iefix</extension>
<mime-type>application/vnd.ms-fontobject</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#latobold</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#latoblack</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#latolight</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#latoregular</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>svg#fontawesomeregular</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
</web-app>
【问题讨论】:
标签: java sqlite tomcat jsf primefaces