gpt4 book ai didi

java - Java Web 应用程序中可能存在内存泄漏 - 对垃圾收集和 session 属性有疑问

转载 作者:行者123 更新时间:2023-12-02 08:24:36 24 4
gpt4 key购买 nike

我一直在使用 VisualVM 在我的电脑上本地分析我的 web 应用程序。我很确定我有一个小的内存泄漏。拍摄应用程序的快照后,我选择了具有最多实例化对象的对象,并查看分配调用树,看看是否可以找到(我的)哪个类对“潜力”做出了贡献。泄漏”。

我在树中找到了三个类,并查看了所精确定位的方法。

这是我的一个 servlet 中的一段代码(一个方法) - 该方法获取我想要保留在 session 中的 session 属性的名称,并删除其余的属性。

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;


try {

conn = ds.getConnection();
stmt = conn.createStatement();

HttpSession session = req.getSession();

getExemptSessionAttributes(Customer_Number,rs,stmt,session);

}//try

catch (Exception e) { }


finally {
if (rs != null) {
try { rs.close(); } catch (SQLException e) { ; }
}
if (stmt != null) {
try { stmt.close(); } catch (SQLException e) { ; }
}
if (conn != null) {
try { conn.close(); } catch (SQLException e) { ; }
}

}//finally

}//post


public void getExemptSessionAttributes(int Customer_Number, ResultSet rs, Statement stmt, HttpSession session) {
try {
rs = stmt.executeQuery("Select Name from exemptsessionattributes");
String[] exemptAttributes = null;
int count = 0;

while(rs.next()) {
count++;
}
rs.beforeFirst();

exemptAttributes = new String[count];
count = 0;

while(rs.next()) {
exemptAttributes[count] = rs.getString(1);
count++;
}
session.setAttribute("ExemptSessionAttributes",exemptAttributes);

//garbage collect
exemptAttributes = null;
}//try
catch(Exception e) {}
}//end

//....

自从分析我的 web 应用程序以来,我迄今为止所做的唯一修改是将 exemptAttributes[] 对象数组设置为 null。

我的问题是 - 如果将 String 数组(或任何对象)设置为 session 属性,是否意味着对该对象的引用(如果未在代码中设置为 null)仍然被“引用”并且不会被垃圾收集?

最佳答案

If a String array (or any object) is set into a session attribute, does that mean that the reference to that object, if not set to null in the code, is still 'referenced' and won't be garbage collected?

不完全是。

如果您将某个对象设置为 session 属性,那么只要 Session 对象可访问,该对象就将继续可访问(并且不会被垃圾回收)。 Session 对象很可能被 servlet 基础设施长期缓存在内存中。

在这种情况下,将 null 分配给局部变量没有任何用处。首先,本地无论如何都会超出范围,从 GC 的角度来看,这具有相同的效果。其次,您刚刚将对象引用复制到一个数据结构(Session 对象)中,该数据结构的生命周期比局部变量更长......因此该对象无论如何都将继续可访问。

简而言之,无论您是否将 null 分配给局部变量,该对象仍然是可访问的。

解决这种“泄漏”的可能方法包括:

  • 不要将对对象的引用放入 session 属性中,
  • 将 session 属性设置为 null,或
  • 调整网络容器的 session 缓存策略,以便从缓存中删除空闲 session 。
  • 实现一项计划,在闲置一段时间后使 session 失效(例如注销用户)。

关于java - Java Web 应用程序中可能存在内存泄漏 - 对垃圾收集和 session 属性有疑问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4799518/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com