System.Data.Linq.Mapping.AttributedMetaDataMember 高内存消耗

huangapple go评论72阅读模式
英文:

System.Data.Linq.Mapping.AttributedMetaDataMember High memory consumption

问题

我正在分析Windows服务项目的转储文件,它使用LinqToSQL来连接数据库。附上堆内存分析摘要。

我可以看到System.Data.Linq.Mapping.AttributedMetaDataMember占用了更多内存,它位于Gen2桶中。

有人可以指导我为什么它在这里占用更多内存吗?

示例代码

public class Program
{
    static void Main(string[] args)
    {
        var detailsDataContext = new DetailsContext();
        var details = detailsDataContext.GetDetails(//param);
    }
}

public class DetailsContext
{
    private readonly IDetailsDataContextRepository _detailsDataContextRepository;

    public DetailsContext()
    {
        _detailsDataContextRepository = new DetailsDataContextRepository();
    }

    public Details GetDetails(string id)
    {
        try
        {
            List<Details> detailsList = _detailsDataContextRepository.GetDetails(id)?.ToList();
            if (detailsList != null && detailsList.Count > 0)
            {
                Detail detail = detailsList.FirstOrDefault();
                return detailsList;
            }

            return null;

        }
        catch (Exception ex)
        {
            //Error log
            return null;
        }
    }

}

public class DetailsDataContextRepository : DataContext, IDetailsDataContextRepository
{

    [Function(Name = "dbo.sp_GetDetails")]
    public IEnumerable<Details> GetDetails([Parameter(Name = "Id", DbType = "VARCHAR(255)")] string id)
    {
        try
        {
            IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id);
            ISingleResult<Details> mRecord = ((ISingleResult<Details>)(result.ReturnValue));
            return mRecord;
        }
        catch (Exception ex)
        {
            TraceError("DetailsDataContext", "GetDetails", ex);
            return new List<Details>();
        }
    }
}

提前感谢。

英文:

I'm analyzing the dump file for the Windows service project, and it is using LinqToSQL to connect databases. Attached dumpe heap memory analysis summary.

I can see the System.Data.Linq.Mapping.AttributedMetaDataMember taking more memory and It's resides in Gen2 bucket.

Can anyone guide me why it's taking more memory here?

Sample Code

public class Program
{
    static void Main(string[] args)
    {
        var detailsDataContext = new DetailsContext();
        var details = detailsDataContext.GetDetails(//param);
    }
}

public class DetailsContext
{
    private readonly IDetailsDataContextRepository _detailsDataContextRepository;

    public DetailsContext()
    {
        _detailsDataContextRepository = new DetailsDataContextRepository();
    }

    public Details GetDetails(string id)
    {
        try
        {
            List&lt;Details&gt; detailsList = _detailsDataContextRepository.GetDetails(id)?.ToList();
            if (detailsList != null &amp;&amp; detailsList.Count &gt; 0)
            {
                Detail detail = detailsList.FirstOrDefault();
                return detailsList;
            }

            return null;

        }
        catch (Exception ex)
        {
            //Error log
            return null;
        }
    }

}

public class DetailsDataContextRepository : DataContext, IDetailsDataContextRepository
{

    [Function(Name = &quot;dbo.sp_GetDetails&quot;)]
    public IEnumerable&lt;Details&gt; GetDetails([Parameter(Name = &quot;Id&quot;, DbType = &quot;VARCHAR(255)&quot;)] string id)
    {
        try
        {
            IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), id);
            ISingleResult&lt;Details&gt; mRecord = ((ISingleResult&lt;Details&gt;)(result.ReturnValue));
            return mRecord;
        }
        catch (Exception ex)
        {
            TraceError(&quot;DetailsDataContext&quot;, &quot;GetDetails&quot;, ex);
            return new List&lt;Details&gt;();
        }
    }
}

Thanks in Advance.
System.Data.Linq.Mapping.AttributedMetaDataMember 高内存消耗

答案1

得分: 2

我将专注于 DetailsContext.GetDetails(string id) 方法,作为如何改进事情的一个示例。

替代以下内容:

public Details GetDetails(string id)
{
    try
    {
        List<Details> detailsList = _detailsDataContextRepository.GetDetails(id)?.ToList();
        if (detailsList != null && detailsList.Count > 0)
        {
            Detail detail = detailsList.FirstOrDefault();
            return detailsList;
        }

        return null;

    }
    catch (Exception ex)
    {
        //错误日志
        return null;
    }
}

你可以获得等效的功能,像这样:

public Details GetDetails(string id)
{
    try
    {
        return _detailsDataContextRepository.GetDetails(id).FirstOrDefault();
    }
    catch (Exception ex)
    {
        //错误日志
        return null;
    }
}

不仅代码少得多,而且速度更快,内存效率更高。正如评论中提到的,这里的主要改进之一是消除了多余的 ToList() 调用,这没有做任何有用的事情。我看到很多程序员采用这种方法,学会不使用它可以显著帮助你的代码。

此外,根据对存储库的 GetDetails() 方法的审查,我还可以删除 try/catch 块,因为该方法本身在可能引发异常的任何地方都使用了 try/catch 并提供了合理的默认值。这意味着我们可以安全地将代码简化为这一行,而不会损失功能:

public Details GetDetails(string id)
{
    return _detailsDataContextRepository.GetDetails(id).FirstOrDefault();
}
英文:

I'll focus on DetailsContext.GetDetails(string id) method as one example of how to improve things.

Instead of this:

public Details GetDetails(string id)
{
    try
    {
        List&lt;Details&gt; detailsList = _detailsDataContextRepository.GetDetails(id)?.ToList();
        if (detailsList != null &amp;&amp; detailsList.Count &gt; 0)
        {
            Detail detail = detailsList.FirstOrDefault();
            return detailsList;
        }

        return null;

    }
    catch (Exception ex)
    {
        //Error log
        return null;
    }
}

You can get equivalent functionality like this:

public Details GetDetails(string id)
{
    try
    {
        return _detailsDataContextRepository.GetDetails(id).FirstOrDefault();
    }
    catch (Exception ex)
    {
        //Error log
        return null;
    }
}

Not only is this MUCH less code, but it's faster and far more memory efficient. As mentioned in the comment, one of the main improvements here is eliminating the spurious ToList() call, which accomplished nothing useful. I see a lot of programmers adopt this crutch, and learning to work without it can dramatically help your code.

Furthermore, based on a review of the repository's GetDetails() method, I might also remove the try/catch block, since that method itself uses a try/catch around anything that's likely to throw and provides a sensible default. It means we can safely get down to this one-liner with no loss of function:

public Details GetDetails(string id)
{
    return _detailsDataContextRepository.GetDetails(id).FirstOrDefault();
}

huangapple
  • 本文由 发表于 2023年2月17日 23:31:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75486265.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定