2012-04-09 57 views
-1

有人幫助我在運行時使用計時器運行一些代碼,但過了一段時間,我看到它只是使用內存而不釋放它。CsharpCodeProvider內存泄漏

我聽到有關AppDomain的信息,但我沒有弄清楚它在哪裏使用它。

AppDomain會幫我解決這個內存泄漏問題嗎?其他任何事情都會幫助我呢?

PS:GC.Collect()沒有幫助。 我確定問題在於,由於我做了一些測試,在運行問題時觀察內存,如果禁用Scripter,它會保持相同的基本數量(基本上),如果我啓動計時器並執行一些代碼不斷增加,並且可以在幾分鐘後得到500k +的內存,所以是的,我相信問題出在CSharpCodeProvider只是使用內存。

這是我的實際代碼,所以如果有人能幫我解決這個問題會很好。

//It is executed in a timer of 500 ms 
private void Run() 
{ 
    foreach (Code ph in codeList) 
    { 
     Code p = ph; 

     new Thread(delegate() 
     { 
      if (Monitor.TryEnter(p)) 
      { 
       Scripter script = new Scripter(); 
       script.Compile(p.Code); 
       Monitor.Exit(p); 
      } 
     }) { IsBackground = true }.Start(); 
    } 
} 

//That's my compile code 
public bool Compile(string script) 
{ 
    CSharpCodeProvider codeprovider = new CSharpCodeProvider(); 
    ICodeCompiler icc = codeprovider.CreateCompiler(); 
    CompilerParameters cp = new CompilerParameters(); 

    cp.ReferencedAssemblies.Add("System.dll"); 
    cp.ReferencedAssemblies.Add(System.Reflection.Assembly.GetExecutingAssembly().Location); 

    cp.TreatWarningsAsErrors = false; 

    cp.MainClass = "CodesRun"; 
    cp.CompilerOptions = "/target:library /optimize"; 
    cp.GenerateExecutable = false; 
    cp.GenerateInMemory = false; //it was true, but same problem 

    TempFileCollection tfc = new TempFileCollection(Application.StartupPath, false); 
    CompilerResults cr = new CompilerResults(tfc); 

    cr = icc.CompileAssemblyFromSource(cp, script); 

    if (cr.Errors.Count > 0) 
    { 
     //Error 
    } 
    else 
    { 
     Assembly assembly = cr.CompiledAssembly; 
     IScript teste = (IScript)assembly.CreateInstance("CodesRun.Script"); 
     teste.Run(); 
    } 
    tfc.Delete(); 
    codeprovider.Dispose(); 

    return true; 
} 
+3

強制性問題:是什麼讓你認爲你有內存泄漏?您使用了哪些工具?那麼導致你得出這個結論的指標究竟是什麼? – 2012-04-09 18:57:54

+0

我在主帖中添加了一些信息,不需要使用任何工具,因爲很容易看到「手動」。 – Kyore 2012-04-09 19:58:08

+1

500k的內存基本上不是很多。你沒有內存泄漏。調用GC.Collect()的結果通常並不表示你是否有內存泄漏。你還沒有說過你使用了什麼工具 - 你不能「手動」看內存。你的意思是你打開電腦機箱,看着物理內存? *當然不是* ...你使用了一個工具。也許* Windows任務管理器*? (順便說一句,這種事情是臭名昭着的) – 2012-04-09 20:13:35

回答

0

嘗試在使用using指令完成處理對象後儘快處理對象。例如:

using(Scripter script = new Scripter()){ 
    script.Compile(p.Code); 
    Monitor.Exit(p); 
} 

這可能不是解決您的泄漏,但應降低內存佔用位(即你應該可以看到內存中儘快收回越好)。

像@Andrew Barber說的,你應該使用一個內存分析工具來驗證是否存在泄漏。我們使用AQTime,但支付了(不太昂貴,但)。免費選項討論here

+0

'Scripter'是否使用非託管內存?這絕對應該完成,但我不確定它是否會對使用的內存有任何影響,因爲Dispose專門用於託管內存以外的內容(由垃圾收集器完全管理) – 2012-04-09 19:05:33

+0

對CSharpCodeProvider不夠了解回答這個,對不起。根據你的其他評論,這是真的,但是IIRC,GC收集的壓力應該比不使用(:P)要高。 – 2012-04-09 19:11:09

+0

對刪除評論感到抱歉;我對這個有點衝突,因爲我想知道你是否對Dispose()可能在這裏沒有具體的正確性。如果OP提供了一些指標,猜測會更容易! – 2012-04-09 19:13:41