none
Multiple app domain in single process - unexplained memory issues RRS feed

  • Question

  • Hi,

    I'm using 2 app domains in 1 process in order to run dynamic code complied using codedom.

    the default app domain is the "main" app domain, it uses a class that inherit MarshalByRefObject to pass data to the other appdomain.
    the second domain uses similar class and IRemoteInterface to expose method to be executed by the "main" domain.

    the second domin receives the script, add required imports, create properties that expose object which the "Main" appdomain passes, compile and via an interface allow the "main" domain to execute the script.

    This allow me to "unload" the dynamic assemblies when required.

    so, i've got things working, an example of some of the  code looks like:

    main domain code:
    setting objects
    objProxy = new HashtableObjectProxy();  
    objProxy.AddObject("textBox2"this.textBox2);  
    objProxy.AddObject("testingEntClass"this.testingEntClass);  
                
    ...
    creating code to be compiled:
    - create imports/using

    create properties and constructor


    StringBuilder sb = 
    new StringBuilder();  
    sb.Append("private HashtableObjectProxy htObjects;" + "\n");  
     
    en = this.objProxy.Objects.GetEnumerator();  
    while (en.MoveNext())  
     {  
        sb.Append("public " + en.Value.GetType().FullName + " " + en.Key + "{ \n");  
        sb.Append("get \n{\n");  
        sb.Append("return (" + en.Value.GetType().FullName + ")htObjects.Objects[\"" + en.Key + "\"]; " + "\n");  
        sb.Append("}\n}\n");  
     }  
    sb.Append("public MyClass(HashtableObjectProxy ht) {" + "\n");  
    sb.Append("htObjects = ht;" + "\n");  
    sb.Append("}" ; 

    creating the class (from the dynamic code):
    object[] eyalloCodeParms = new object[1];  
    eyalloCodeParms[0] = objProxy;  
                 
    loObject = (IRemoteInterface) Activator.CreateInstanceFrom(  
                    assemblyFile, typeName, false, bfi, null, eyalloCodeParms,  
                    nullnullnull ).Unwrap();  
     
    loRemote = (IRemoteInterface)loObject;  
     
     

    executing the script :
    object myResult = loRemote.Invoke("DynamicCode"null); 

    now, i've started checking the solution from memory and performance issues.
     therefore i used a class that holds a huge array of strings. i pass it  to the constructor. the script itself access a string and set a textbox1.Text value accordingly.

    the steps include:
    1. load form and the main appdomain
    2. create the class at "main" appdomain
    3. create second app domain.
    4. invoke dynamic code creation.
    5. compile code
    6. create dynamic class object
    7. execute method.
    8. unload the secondary appdomain

    i see 1 spike of process private memory when i create the class at phase 2 (make sense)
    then i see another spike when executing the method, a small decline when i unload the appdomain.
    but the memory release is relative small to the second growth, which i can explain.

    it should be passed by ref,  if i did it wrong it shouldn't work (the textbox changed, and when i change the object data in a script it changes in the proper places) and even if a duplicate is created, , i should see a decline after uploading the appdomain.

    does anyone have an idea why?

    thanks in advance.

    Eyal


    thanks in advance

    Tuesday, November 25, 2008 3:35 PM

Answers

  • The CLR does not necessarily release memory back to the operating system.  Usually, the CLR keeps it allocated for future re-use by the same application.

    You might find GC.GetTotalMemory(true) or some of the performance counters to be more useful when getting an idea of how much memory is "in use".

    • Marked as answer by Eyal Fingold Wednesday, November 26, 2008 10:52 AM
    Wednesday, November 26, 2008 12:22 AM