释放内存,静态类析构函数?

3

我有一个静态类,用作我的网站数据层。在这个类中,我有字符串数组来存储查询信息,以便稍后访问。以下是我的类和相关方法的一部分:

public static class data_layer
{
    private static string[] items;
    private static string[] description;

    //will return description for an item id. if no item id is found, null is returned
    public static string getDesc(string key)
    {
        int i = 0;
        bool flag = false;
        //search for the item id to find its index
        for(i = 0; i < items.Length; i++)
        {
            if(items[i] == key)
            {
                flag = true;
                break;
            }
        }
        if(flag)
            return description[i];
        else
            return null;
    }
    public static string[] getItems()
    {
        return items;
    }

    public static bool setItemsAndDescriptions()
    {
        ArrayList itemIDs = new ArrayList();
        ArrayList itemDescs = new ArrayList();

        SqlConnection sqlConn = new SqlConnection();
        sqlConn.ConnectionString = ConfigurationManager.ConnectionStrings["MAS200RAWConnectionString"].ConnectionString;
        string query = "SELECT ItemNumber, ItemDescription FROM OUS_IM1_InventoryMasterfile " +
            "WHERE ItemNumber LIKE 'E%' OR ItemNumber LIKE 'B%' OR ItemNumber LIKE 'D%'";

        try
        {
            sqlConn.Open();
            SqlCommand sqlComm = new SqlCommand();
            sqlComm.Connection = sqlConn;
            sqlComm.CommandType = CommandType.Text;
            sqlComm.CommandText = query;
            SqlDataReader reader = sqlComm.ExecuteReader();
            if (reader == null)
                return false;

            //add the queried items to the ddl
            while (reader.Read())
            {
                itemIDs.Add(reader["ItemNumber"].ToString().Trim());
                itemDescs.Add(reader["ItemDescription"].ToString().Trim());
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
        finally
        {
            sqlConn.Close();   //NOTE: I HAVE A BREAKPOINT HERE FOR DUBUGGING
        }

        items = itemIDs.ToArray(typeof(string)) as string[];
        description = itemDescs.ToArray(typeof(string)) as string[];
        return true;
    }
}

这一切都很好,但是我将断点放在我说的位置时,我注意到类成员items和description在我的程序执行期间(本地asp开发服务器)保留了它们分配的内存和元素。为什么当程序结束时(退出浏览器或停止调试模式)这些内存没有被释放?有没有办法手动释放这些内存并为静态类创建一个析构函数?


1
顺便说一下,那段代码完全不支持多线程(静态方法通常应该是线程安全的),并且通过将“items”从类中返回,数据稍微有被意外修改的风险。 - Marc Gravell
@Nicklamort - 你正在编写一个Web应用程序,对吧?那么,Web服务器运行多个线程。因此,除非你只有一个用户,并且他们承诺一次只加载一个页面,否则你应该真的考虑线程安全性。 - Marc Gravell
4
虽然这不是主题,但您的代码看起来很糟糕。除非您使用.NET 1.1,否则请用其泛型版本List<T>替换ArrayList。 其次,标志变量没有用处。尝试重构代码。 此外,请查看C#命名约定,因为您似乎是Java开发人员:http://msdn.microsoft.com/en-us/library/xzf533w0%28v=vs.71%29.aspx - dzendras
1
克里斯是正确的。不要被打击。将我的评论视为旨在帮助您编写更好代码的建议。事实上,我们每个人都以与您现在相同的方式编写代码,但几年后您会获得经验,这使您看到应该如何完成它。祝你好运! - dzendras
2
@dzendras - 你的意思是“不要气馁”吗? - Marc Gravell
显示剩余15条评论
2个回答

7

没有静态类的析构函数,但您可以使用以下方式:

public static void Unload() {
    items = description = null;
}

关于“为什么程序结束时这个内存没有被释放” - 如果您指的是退出浏览器,那么服务器甚至不会注意到。只有当应用程序池(在IIS中)停止时才会清理它。


哦,我明白了。我想当你退出或离开网站时,服务器会结束应用程序并释放该用户的所有内存。谢谢,知道这一点肯定会帮助我编写我的代码 :) 顺便说一句,我假设我必须自己调用Unload(),它不会像析构函数一样自动执行? - Nick Rolando
@Nicklamort - 请记住,所有用户都在使用相同的静态数据。为用户A卸载它也会为用户B和用户C在3个浏览器中的14个选项卡卸载它。 - Marc Gravell
马克,如果我的数据在应用程序池关闭之前没有被清理干净,那么是否有可能向数据库中插入新记录,并且用户尝试重新加载页面,从而将新大小的数组加载到已经定义好的数组中并抛出错误?如果是这样,将其设置为null是否可以允许重新分配? - Nick Rolando
哈哈,我明白了,现在我知道只有当应用程序池关闭时才会释放它,谢谢^^ - Nick Rolando

2

这是因为这些字段是静态的,停止调试并不意味着WebDev服务器已关闭。 如果您想按用户存储字符串,请将它们放入会话对象中。它保证它们将对每个用户可用,并且在会话结束(超时或关闭浏览器窗口)时将被删除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接