【问题标题】:deallocating memory, static class destructor?释放内存,静态类析构函数?
【发布时间】:2011-01-13 20:24:11
【问题描述】:

我有一个静态类用作我网站中的数据层。在这个类中,我有存储查询信息的字符串数组,我以后可以访问这些信息。这是我的课程的一部分和有问题的方法:

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;
    }
}

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

【问题讨论】:

  • 顺便说一下,该代码是完全非线程安全的(静态方法通常应该是线程安全的),并且通过返回 items
  • 我对线程一无所知,真的。刚毕业,在 4 年的编程专业中从未提到过多线程.. 对此非常生气
  • 这是一个离题但你的代码看起来很糟糕。除非您使用 .NET 1.1,否则将 ArrayList 替换为其通用版本 List。其次标志变量是无用的。尝试重构代码。还请查看 C# 命名约定,因为您似乎是 Java 开发人员:msdn.microsoft.com/en-us/library/xzf533w0%28v=vs.71%29.aspx
  • 克里斯是对的。不要被鼓励。将我的评论视为旨在帮助您编写更好代码的建议。事实上,我们每个人都以与您现在相同的方式编写代码,但几年后您会获得经验,这会让您了解应该如何完成。祝你好运!
  • @dzendras - 你的意思是“不要气馁”吗?

标签: c# asp.net memory-management


【解决方案1】:

不,没有静态类的析构函数,但您可以执行以下操作:

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

关于“为什么程序结束时没有释放此内存” - 如果您的意思是退出浏览器,服务器甚至不会注意到这一点。当应用程序池(在 IIS 中)死亡时,它将被清除。

【讨论】:

  • 哦,我明白了。我想当您退出或浏览网站时,服务器会结束应用程序并为该用户释放所有内存。谢谢,知道这将有助于编写我的代码:) ps-btw,我假设我必须自己调用 Unload(),它不会像析构函数那样自动?
  • @Nicklammort - 请记住,所有您的用户都在使用相同静态数据。为用户 A 卸载它也为用户 B 卸载它,以及用户 C 在 3 个浏览器中的所有 14 个选项卡
  • Marc,如果我的数据在 app-pool 死掉之前没有被清理,是否有可能将新记录输入到数据库中,并且用户会尝试重新加载页面,加载将新大小的数组放入我已经定义的数组中并引发错误?如果是这样,将其设置为 null 是否允许重新分配?
  • 哈哈,我明白了,现在我知道它不会被释放,直到 app-pool 死掉,thx^^
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2016-10-25
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2013-01-04
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多