This is a migrated thread and some comments may be shown as answers.

Free memory of database data

5 Answers 89 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Jürgen
Top achievements
Rank 1
Jürgen asked on 07 Sep 2011, 11:09 AM
Hello Telerik team!
I have an entity [Test]. It has many fields. These fields store huge data. (I use many CLOB, which is seralized to many [Transient fields]). In my application I need to show in a Grid a list of these tests (I show only Name and Date). But if I load all of tests from DB - my application require more and more memory. I want to load from Tests only Name and Date fields at first (and maybe pk Nr also). This info is enough to show in Grid. And then user select one Test and analyse it (analyse all necessary data). And now I need load all data for concrete Test. After user commit this Test - I need free memory of it in scope.

So, How I can clear all info about loaded/commited Test from scope?

5 Answers, 1 is accepted

Sort by
0
Jan Blessenohl
Telerik team
answered on 07 Sep 2011, 01:40 PM
Hello Jürgen,
To lazy load fields, you have to set the strategy to 'Lazy'. If you use the designer, just select the property and change it in the property window.
If you have a situation where you need more data immediately, please use the FetchStrategy to optimize the generate sql statements.
To free the memory, you have to dispose the scope. We are trying to keep our caches small by using weak references but you never know when the memory is freed.

All the best,
Jan Blessenohl
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's SQL Server Community Awards. We are competing in TWO categories and every vote counts! VOTE for Telerik NOW >>

0
Jürgen
Top achievements
Rank 1
answered on 09 Sep 2011, 01:12 PM
I write as in Telerik example about Fetch Plan:
my Entity:
public class TestGen : IInitializeTransients
{
        [FetchField("fgTestGen")]
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
  
        [FetchField("fgTestGen")]
        private DateTime testBegin;
        public DateTime TestBegin
        {
            get { return testBegin; }
            set { testBegin = value; }
        }
  
        public string CLOBData{get;set;} // it is a CLOB-field
        //....
}

FetchPlan.cs:
public class FetchPlans
   {
        public static FetchPlan  fpTestGen =
            new FetchPlan( 
            new string[] { "fgTestGen"}, 
            FetchPlan.DefaultMaxDepth,
            FetchPlan.NoLimit ) ;
   }

ScopeProvider.cs:
static public IObjectScope ObjectScope()
{
        // ...
        scope.FetchPlan.Clear();
        scope.FetchPlan.Add("fgTestGen");
        scope.FetchPlan.MaxDepth = 3;
        return scope;            
}

but when I load TestGen from db:
var result = from p in scope.Extent<TestGen>() select p;
in result.ToList() in debug mode I see all loaded fields (not only marked as FetchField). CLOBData is loaded too. But I don't ned load it at this moment.
Also InitializeTransient-methods are called too. I don't need it too.
What I do incorrect?

Thanks!
0
Jan Blessenohl
Telerik team
answered on 09 Sep 2011, 04:25 PM
Hello Jürgen,
You are using the debugger ;)

Our lazy loading code is injected into your properties, this means if the debugger shows the content of the properties in the watch window, the data is loaded. To see the real situation you have to switch off property evaluation in the Tools->Options->Debugging window.

Kind regards,
Jan Blessenohl
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's SQL Server Community Awards. We are competing in TWO categories and every vote counts! VOTE for Telerik NOW >>

0
Jürgen
Top achievements
Rank 1
answered on 10 Sep 2011, 07:15 AM
But how can I check that I work correct with FetchPlans?
If I switch off property evaluation in the Tools->Options->Debugging window - I can't see even my FetchFields!
Where I have to see and check - my FetchFields are initialized, but others - not. ??
0
Jan Blessenohl
Telerik team
answered on 12 Sep 2011, 01:39 PM
Hi Jürgen,
You are right, analyzing loaded fields if you use auto puberties is complected. I have written two static functions that you can call in your debugger or in your application to print the field status to console or to the debugger windows:
private static void DumpLoadedFieldsConsole(Object obj)
{
    var ret = GetLoadedFields(obj);
    foreach (var t in ret)
    {
        if (t.Item2)
            Console.WriteLine("Field: " + t.Item1 + " is loaded.");
        else
            Console.WriteLine("Field: " + t.Item1 + " is notloaded.");
    }
}
 
private static void DumpLoadedFieldsDebugger(Object obj)
{
    var ret = GetLoadedFields(obj);
    foreach (var t in ret)
    {
        if (t.Item2)
            System.Diagnostics.Debug.WriteLine("Field: " + t.Item1 + " is loaded.");
        else
            System.Diagnostics.Debug.WriteLine("Field: " + t.Item1 + " is notloaded.");
    }
}
 
private static List<Tuple<string, bool>> GetLoadedFields(object obj)
{
    var ret = new List<Tuple<string,bool>>();
    var pc = obj as Telerik.OpenAccess.SPI.dataobjects.PersistenceCapable;
    var pmp = pc.OpenAccessEnhancedGetPersistenceManager();
 
    // call OpenAccessRuntime.DataObjects.PMProxy.getRealPM return OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp
    var runtimeAssemly = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName.StartsWith("Telerik.OpenAccess.Runtime,")).Single();
    var pmpType = runtimeAssemly.GetTypes().Where(x => x.FullName == "OpenAccessRuntime.DataObjects.PMProxy").Single();
    var method = pmpType.GetMethod("getRealPM");
    var pm = method.Invoke(pmp, null);
 
    // OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.GetInternalStateManagerNoException returns OpenAccessRuntime.DataObjects.PCStateMan
    var pmImpType = runtimeAssemly.GetTypes().Where(x => x.FullName == "OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp").Single();
    method = pmImpType.GetMethod("GetInternalStateManagerNoException");
    var stateMan = method.Invoke(pm, new object[] { pc });
 
    // access OpenAccessRuntime.DataObjects.PCStateMan.state return OpenAccessRuntime.common.State
    var stateManType = runtimeAssemly.GetTypes().Where(x => x.FullName == "OpenAccessRuntime.DataObjects.PCStateMan").Single();
    var field = stateManType.GetField("state", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    var state = field.GetValue(stateMan) as OpenAccessRuntime.common.State;
 
    var cmd = state.getClassMetaData();
    foreach (var fmd in cmd.fields)
    {
        var loaded = state.containsField(fmd.stateFieldNo);
        ret.Add(new Tuple<string,bool>(fmd.PropertyName??fmd.name,loaded));
    }
    return ret;
}

You have to add a reference to the Telerik.OpenAccess.Runtime assembly.

Best wishes,
Jan Blessenohl
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's SQL Server Community Awards. We are competing in TWO categories and every vote counts! VOTE for Telerik NOW >>

Tags
General Discussions
Asked by
Jürgen
Top achievements
Rank 1
Answers by
Jan Blessenohl
Telerik team
Jürgen
Top achievements
Rank 1
Share this question
or