Hello,
I have a test program with UltraGrid and UltraDataSource. DataSource has simple hierarchy with one child band. Root and child bands has no columns and DataSource has no real data. Then I set row count to 100000 record. After calling ExpandAll() method for UltraGrid.Rows memory usage dramatically increases ( from 41.5 to 120 Mb with LoadStyle.PreloadRows set ).
We are using VS 2008 SP1 and NetAdvantage 2008 Vol.2.
I'd like to understand the reason of memory growth and if it's possible ways of avoiding it. Thanks in advance.
Seems pretty straightforward to me. You are forcing the creation of 100,000 UltraDataRows in addition to 100,000 UltraGridRows. So this seems perfectly reasonable to me.
If you are interesting in saving memory, you should check out the WinGrid Performance Guide.
Hi, Mike,
Thanks for reply but unfortunately it doesn't help me at all. I can't understand how am I forcing creation of 100,000 UltraDataRows if they are already created. As I mentioned before, LoadStyle property is set to PreloadRows which means that all DataRows are already created before my call of ExpandAll() method. Here is my code:
ultraDS1.Band.Key = "Main";
I'm not sure I follow you.
As I believe I explained, if you call ExpandAll on the grid, the grid has no choice but to loop through every row and set a flag indicating that the row is expanded. The grid has no way of knowing that the rows don't really exist in the DataSource. As far as the grid is concerned, the DataSource returns the row count and those rows have to be treated as though they exist. So calling ExpandAll loops through every row and the grid has to create objects for those rows and their potential child rows - since you are asking it to expand.
Calling ExpandAll is not, by nature, a very efficient operation. If you don't want the grid to create all those objects, then why call this method? What you are asking for here seems to be self-contradicting. You want to expand all rows without having any rows.
s_ledenev said:So, if I can't get rid of these memory allocations, can I inform the grid in some way not to paint an expand icon near rows which has no data
Once again, this seems impossible. The only way the grid knows if a row has child rows is by creating a Row object and attempting to access the child rows from the data source.
Well, Mike, I've performed some additional research using DevPartner. Source code line "ultraDS1.Rows.SetCount( 100000 );" was changed to
for( Int32 i = 0; i < 100000; i++ ) { UltraDataRow row = ultraDS1.Rows.Add( new Object[]{ } ); }
just for explicit creation of UltraDataRow. On the screenshot below (Scr.1) we can see memory allocations before ExpandAll() and this cause no surpise and absolutely expectable.
Scr.1 Before ExpandAll() call
On the second screen below we can see memory allocations after ExpandAll(). A lot of additional objects were created for data that doesn't even exist. That is very disappointing.
Scr.2 After ExpandAll() call
So, if I can't get rid of these memory allocations, can I inform the grid in some way not to paint an expand icon near rows which has no data. I need this to prevent user's actions and additional unnecessary memory allocations.
Thanks in advance.
Well, the rows are lazily created. So caling SetCount is probably just setting a member variable without actually creating any rows. When you call ExpandAll, the grid has to loop through every row and check for child rows and expand the row. So it is at that point that the row objects actually get created.