UiPathのメモリリーク対策 解決編
2021年04月16日
今回もRPAのメモリリーク対策の話。
再現OutOfMemoryが発生している状態の端末を触ることができた。
タスクマネージャーを開くと「UiPath.Executor.exe」が
1.4Gもメモリ食ってた。
前々回の記事で書いた「rundll32.exe」でメモリ解放する方法を試したけど、
「UiPath.Executor.exe」のメモリ使用量は全く変わらず。
(「rundll32.exe advapi32.dll,ProcessIdleTasks」をCMDで実行。)
ロボットがメモリを掴んだまま膨れ上がって落ちるようで、
ガベージコレクションのような方法は効果がなさげ。
さらに調べていくと、モジュールを呼び出す際に
「UiPath.Executor.exe」を別プロセスとして起動させることができるらしい。
再現OutOfMemoryが発生している状態の端末を触ることができた。
タスクマネージャーを開くと「UiPath.Executor.exe」が
1.4Gもメモリ食ってた。
前々回の記事で書いた「rundll32.exe」でメモリ解放する方法を試したけど、
「UiPath.Executor.exe」のメモリ使用量は全く変わらず。
(「rundll32.exe advapi32.dll,ProcessIdleTasks」をCMDで実行。)
ロボットがメモリを掴んだまま膨れ上がって落ちるようで、
ガベージコレクションのような方法は効果がなさげ。
さらに調べていくと、モジュールを呼び出す際に
「UiPath.Executor.exe」を別プロセスとして起動させることができるらしい。
1 Isolated(分離)プロパティの概要
https://www.uipath.com/ja/blog/developer/invoke-workflow-file-tips
呼び出しプロパティのチェックボックスにチェックを入れるだけw
これなら以下で紹介しているガベージコレクションも効果が出るかも。
OutOfMemory例外への対応
https://www.uipath.com/ja/resources/knowledge-base/out-of-memory
GCを明示的に呼び出す方法として、以下の3ステップを実行する方法が紹介されている。
① アクセス不可能なオブジェクトを除去
メソッドを呼び出す
TargetType:System.GC
TargetObject:空欄
MethodName:Collect
② ファイナライゼーションが終わるまでスレッド待機
メソッドを呼び出す
TargetType:System.GC
TargetObject:空欄
MethodName:WaitForPendingFinalizers
③ ファイナライズされたばかりのオブジェクトに関連するメモリを開放
メソッドを呼び出す
TargetType:System.GC
TargetObject:空欄
MethodName:Collect
以下の論法で上席へ説明。
前回ログを仕掛けて、メモリリークしている処理を特定した。
その処理後にGCでメモリ回収を試みるが、そのままではメモリが解放されないので
当該処理を別プロセスとして呼び出して、明示的にGCを呼び出す。
実際の対策は、GCが頻発しないようファイルループを呼び出し元で
①~③の処理を追加。
効果を確認するため、ファイルループ処理を呼び出し前後および
明示的GC処理の前後にログを設置。
出力されるメモリ使用量は、ログ出力処理を行ったロボットのものなので、
プロセスを分離する場合は、プロセス毎に番号を分けた方がわかりやすい。
「UiPath.Executor.exe」としての使用量は、合計値になるので注意。
リリースして確認した結果、
これまで1日で1G増加していたメモリ使用量が
1日50Mまで減った。
これなら1か月くらいは耐えられそう。
明示的GCの効果というよりかは、プロセスを分離したことで
重たい処理を終えたプロセスが一旦終了することで
メモリを回収できるようになるのがでかい気がする。
ロボットのロジックを変更せずに対策をすることができて良かった。
更なる対策はこちら
PR
Comment