首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dotMemory和跟踪内存泄漏

dotMemory和跟踪内存泄漏
EN

Stack Overflow用户
提问于 2017-01-22 06:17:27
回答 2查看 1K关注 0票数 2

我有一个我认为基本的web应用程序MVC,EF6。用户有一个仪表板,该仪表板显示一个表,其中包含来自两个不同数据库系统的数据。MSSQL和Informix (使用IBM.Data.Informix)。

随着时间的推移,IIS进程只会不断蚕食ram。我抓取了dotMemory来帮助我定位它,但现在我正在试图弄清楚如何读取这些数据。

我让网页保持打开状态,每隔10秒就会有一个Ajax调用返回新数据。

第四个快照是在第三个快照之后几个小时拍摄的。

总数与下面的数字不匹配,但有些东西不是它应该的样子。

下面的图片似乎告诉我,我的应用程序最多只使用10mb。

我还在研究堆,但看起来这不是最重要的地方。

我仍然在挖掘视频和指南,以帮助我找到这个问题。我使用了很多内置的框架,我真的看不出我正在使用的代码有什么问题,除非有一个bug,或者我真的遗漏了一些我不应该在代码中做的事情。

DatabaseManager

代码语言:javascript
复制
public class DatabaseManager : IDisposable
{
    private bool disposed = false;
    private SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

    private PatientCheckinEntities db { get; set; }

    private IfxConnection conn { get; set; }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public DatabaseManager()
    {
        string ifxString = System.Configuration.ConfigurationManager.ConnectionStrings["ifx"].ConnectionString;
        conn = new IfxConnection(ifxString);
        db = new PatientCheckinEntities();
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
            return;

        if (disposing)
        {
            handle.Dispose();

            IfxClose();
            conn.Dispose();
            db.Dispose();
        }

        disposed = true;
    }

    private void IfxClose()
    {
        if (conn.State == System.Data.ConnectionState.Open)
        {
            conn.Close();
        }
    }

    private void IfxOpen()
    {
        if (conn.State == System.Data.ConnectionState.Closed)
        {
            conn.Open();
        }
    }

    public ProviderModel GetProviderByResourceID(string id)
    {
        ProviderModel provider = new ProviderModel();

        using (IfxDataAdapter ida = new IfxDataAdapter())
        {
            ida.SelectCommand = new IfxCommand("SELECT description FROM sch_resource WHERE resource_id = ? FOR READ ONLY", conn);
            IfxParameter ifp1 = new IfxParameter("resource_id", IfxType.Char, 4);
            ifp1.Value = id;
            ida.SelectCommand.Parameters.Add(ifp1);

            IfxOpen();
            object obj = ida.SelectCommand.ExecuteScalar();
            IfxClose();
            if (obj != null)
            {
                string name = obj.ToString();

                provider.ResourceID = id.ToString();
                string[] split = name.Split(',');

                if (split.Count() >= 2)
                {
                    provider.LastName = split[0].Trim();
                    provider.FirstName = split[1].Trim();
                }
                else
                {
                    provider.LastName = name.Trim();
                }

                ProviderPreference pp = db.ProviderPreferences.Where(x => x.ProviderID.Equals(id, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

                int globalWait = Convert.ToInt32(GetConfigurationValue(ConfigurationSetting.WaitThreshold));

                if (pp != null)
                {
                    provider.Preferences.DisplayName = pp.DisplayName;
                    provider.Preferences.WaitThreshold = pp.WaitThreshold.HasValue ? pp.WaitThreshold.Value : globalWait;
                }
                else
                {
                    provider.Preferences.WaitThreshold = globalWait;
                }
            }
        }

        return provider;
    }

    public List<PatientModel> GetCheckedInPatients(List<string> providers)
    {
        List<PatientModel> patients = new List<PatientModel>();

        foreach (string provider in providers)
        {
            List<PatientModel> pats = db.PatientAppointments
                        .Where(x => provider.Contains(x.ProviderResourceID)
                        && DbFunctions.TruncateTime(x.SelfCheckInDateTime) == DbFunctions.TruncateTime(DateTime.Now))
                            .Select(x => new PatientModel()
                            {
                                Appointment = new AppointmentModel()
                                {
                                    ID = x.AppointmentID,
                                    DateTime = x.AppointmentDateTime,
                                    ArrivalTime = x.ExternalArrivedDateTime
                                },
                                FirstName = x.FirstName,
                                LastName = x.LastName,
                                SelfCheckIn = x.SelfCheckInDateTime,
                                Provider = new ProviderModel()
                                {
                                    ResourceID = x.ProviderResourceID
                                }
                            }).ToList();

            patients.AddRange(pats.Select(x => { x.Provider = GetProviderByResourceID(x.Provider.ResourceID); return x; }));
        }

        using (IfxDataAdapter ida = new IfxDataAdapter())
        {
            ida.SelectCommand = new IfxCommand("SELECT arrival_time::char(5) as arrival_time FROM sch_app_slot WHERE appointment_key = ? FOR READ ONLY", conn);

            IfxOpen();
            foreach (PatientModel patient in patients)
            {
                ida.SelectCommand.Parameters.Clear();
                IfxParameter ifx1 = new IfxParameter("appointment_key", IfxType.Serial);
                ifx1.Value = patient.Appointment.ID;
                ida.SelectCommand.Parameters.Add(ifx1);

                using (IfxDataReader dr = ida.SelectCommand.ExecuteReader())
                {
                    while (dr.Read())
                    {
                        if (dr.HasRows)
                        {
                            string arrival = dr["arrival_time"].ToString();

                            if (!string.IsNullOrWhiteSpace(arrival) && !patient.Appointment.ArrivalTime.HasValue)
                            {
                                PatientAppointment pa = new PatientAppointment();
                                pa.AppointmentID = patient.Appointment.ID;
                                pa.AppointmentDateTime = patient.Appointment.DateTime;
                                pa.FirstName = patient.FirstName;
                                pa.LastName = patient.LastName;

                                string dt = string.Format("{0} {1}", patient.Appointment.DateTime.ToString("yyyy-MM-dd"), arrival);
                                pa.ExternalArrivedDateTime = DateTime.ParseExact(dt, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture);
                                patient.Appointment.ArrivalTime = pa.ExternalArrivedDateTime;
                                pa.ProviderResourceID = patient.Provider.ResourceID;
                                pa.SelfCheckInDateTime = patient.SelfCheckIn;

                                db.PatientAppointments.Attach(pa);
                                db.Entry(pa).State = EntityState.Modified;
                                db.SaveChanges();
                            }
                        }
                    }
                }
            }
            IfxClose();
        }


        patients = patients.Select(x => { x.Appointment.WaitedMinutes = (int)Math.Round(((TimeSpan)x.Appointment.ArrivalTime.Value.Trim(TimeSpan.TicksPerMinute).Subtract(x.SelfCheckIn.Trim(TimeSpan.TicksPerMinute))).TotalMinutes); return x; }).ToList();

        List<PatientModel> sorted = patients.Where(x => !x.Appointment.ArrivalTime.HasValue).OrderBy(x => x.SelfCheckIn).ThenBy(x => x.Provider.ResourceID).ToList();
        sorted.AddRange(patients.Where(x => x.Appointment.ArrivalTime.HasValue).OrderBy(x => x.Appointment.DateTime).ThenBy(x => x.Provider.ResourceID));

        return sorted;
    }

    private string GetConfigurationValue(string id)
    {
        return db.Configurations.Where(x => x.ID.Equals(id)).Select(x => x.Value).FirstOrDefault();
    }
}

控制器

代码语言:javascript
复制
[HttpPost]
[Authorize]
public ActionResult GetCheckedIn(List<string> provider)
{
    DashboardViewModel vm = new DashboardViewModel();
    try
    {
        if (provider.Count > 0)
        {
            using (DatabaseManager db = new DatabaseManager())
            {
                vm.Patients = db.GetCheckedInPatients(provider);
            }
        }
    }
    catch (Exception ex)
    {
        //todo
    }
    return PartialView("~/Views/Dashboard/_InnerTable.cshtml", vm);
}
EN

回答 2

Stack Overflow用户

发布于 2017-01-23 21:10:10

您的应用程序会消耗大量的本机内存,而不是.NET内存。看看.NET内存消耗,它大约是12Mb,并且不是很密集地增长。似乎你没有在一些使用本机内存的对象上调用Dispose方法,例如数据库连接对象或类似的对象。检查一些这样的物体,如果你不释放它们,它们的数量将不断增加。

票数 2
EN

Stack Overflow用户

发布于 2020-02-12 03:24:47

我看到你在用System.xml.Schema……根据版本的不同,将为每个大小约为80K的实例创建非托管内存泄漏。所以,每12次使用,你就会在非托管内存中有一个1兆内存泄漏。如果可能,缓存它,而不是每次都创建一个新的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41785141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档