Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
125
Memory Issues???
posted

I'm getting my chops busted about memory usage for a DOTNET app that is using ultragrids all over the place.  One in particular can get pretty big.  Right now I'm testing with close to 30,000 rows.  I've tweaked my InitializeRow code to make it as efficient as I think I possibly can, which has saved us some memory.  My argument is that we are dealing with a ton of data that gets loaded into memory when the grid gets refreshed and/or populated with data and there's not much we can do. It is what it is.  I have 3GB of RAM on my PC and I have no issues with the app.  One of our testers has 1GB of RAM and he has a lot of problems running other apps while the DOTNET app is running and using up a lot of memory.  Even with 30,000 records in the grid I've never seen the RAM get higher than 600-650 MB for the app.  So it seems like it's more of a hardware issue.  Anyway ...

So I come here asking you guys to take a look at my InitializeRow code to see if there are any inefficiencies in there that I could improve upon.  I'm using a separate class which contains about 8-10 appearance objects that I set up at app load time to set appearances for some rows and cells.  That has saved us quite a bit of memory versus the way I did it initially - create appearance objects for each row on the fly.  I also am using some check mark images (2k) to display boolean data.  I thought these may be increasing memory, but recent testing proves otherwise.  Here are some benchmark numbers and my InitializeRow code.  Any advice you guys have is much appreciated ...

Oh, and let's leave the LoadOnDemand out of the conversation if we can.  We don't necessarily like the way that functions, so we are looking at every possibility of reducing memory usage before we throw in the towel and go that route. 

 

 

No Images

Images

No Appearances

Initial Load

252 MB

250

242

1st Refresh

425

431

414

2nd Refresh

435

428

343

3rd Refresh

432

422

418

 

// Set tool tip text for row

string status = e.Row.Cells["STATUS"].Value.ToString();

string fldrKey = e.Row.Cells["FOLDER KEY"].Value.ToString();

e.Row.ToolTipText = "ID: " + fldrKey + ", STATUS: " + status;

// Color code each row based on its status value

switch (status)

{

    case "NEW":

        e.Row.Appearance = UltraGridAppearances.gridAppearances["Red"];

        break;

    case "CANCELLED":

        e.Row.Appearance = UltraGridAppearances.gridAppearances["Gainsboro"];

        break;

    case "CLOSED":

        e.Row.Appearance = UltraGridAppearances.gridAppearances["White"];

       break;

    case "IN PROGRESS":

        // Color row differently based on whether or not T/S's are assigned

        string tsStatus = e.Row.Cells["TRBL SHTR STATUS"].Value.ToString();

        if (tsStatus == "RELEASED" || tsStatus == "")

        {

            e.Row.Appearance = UltraGridAppearances.gridAppearances["Yellow"];

        }

        else

        {

            e.Row.Appearance = UltraGridAppearances.gridAppearances["Lime"];

        }

        break;

    case "IN PLANNING":

        e.Row.Appearance = UltraGridAppearances.gridAppearances["Yellow"];

        break;

    case "READY FOR WORK":

        e.Row.Appearance = UltraGridAppearances.gridAppearances["Orange"];

        break;

}

// Set cell images for cells containing TRUE or FALSE

if (e.Row.IsDataRow)

{

    for (int i = 0; i < e.Row.Cells.Count; i++)

    {

        switch (e.Row.Cells[i].Value.ToString().ToUpper())

        {

            case "TRUE":

                // Make data value transparent so we can still sort on the data in the

                // column and have an image present

                e.Row.Cells[i].Appearance = UltraGridAppearances.gridAppearances["GreenCheck"];

                break;

            case "FALSE":

                // Make data value transparent so we can still sort on the data in the

                // column and have an image present

                e.Row.Cells[i].Appearance = UltraGridAppearances.gridAppearances["NoImage"];

                break;

        }

    }

}

// Set images for indicator columns

foreach (KeyValuePair<int, string> kvp in _indDict)

{

    // Go through all the indicator columns, check the current cell value

    // and set the image accordingly

    string colName = kvp.Value;

    if (e.Row.Band.Columns.Exists(colName))

    {

        // Set column heading caption to the original column name from the proc

        e.Row.Band.Columns[colName].Header.ToolTipText = colName;

        switch (e.Row.Cells[colName].Value.ToString())

        {

            case "1":

                e.Row.Cells[colName].Appearance = UltraGridAppearances.gridAppearances["GreenCheck"];

                break;

            case "2":

                // This will be for indicators that need to display a different icon for a NEW state

                e.Row.Cells[colName].Appearance = UltraGridAppearances.gridAppearances["RedCheck"];

                break;

            default:

                // Make data value transparent so we can still sort on the data in the

                // column and have an image present

                e.Row.Cells[colName].Appearance = UltraGridAppearances.gridAppearances["NoImage"];

                break;

        }

    }

}

 

Parents
No Data
Reply
  • 469350
    Offline posted

    One thing I noticed right away that you could improve is the use of cells. The grid tries not to create UltraGridCell objects until they are needed. Sometimes, you have no choice but to create the cell. For example, you need the cell to apply an appearance to it. 

    But you can get the Value or Text of the cell without creating it. 

    This:

     string status = e.Row.Cells["STATUS"].Value.ToString();

    can be replaced with:

      string status = e.Row.GetCellValue("STATUS").ToString();

    The GetCellValue and GetCellText methods allow you to get the value or text of the cell without forcing the cell object to be created. 

    So it seems like you can avoid creating quite a number of cells here and when you multiply that by 30,000 rows, that should give you back a nive chunk of memory.

Children