SWIGを使用してC++で書かれたPythonのライブラリをラップしようとしています。ライブラリは、バイトバッファをパラメータとして受け入れる関数呼び出しを使用します。 Pythonでは、私はSWIGから%array_classを使ってこれらのバイトバッファを作成しています。私はこれをテストするために概念実証プログラムを作ったので、これらのバッファをC++に渡すことに伴う大きなメモリリークに気付きました。具体的には、以下のコードを実行すると、Pythonアプリケーション(タスクマネージャで確認)のメモリ使用量が着実に増加し、プログラムが停止する場所は約250MBになります。 Cからの出力は、プログラムが期待通りにを実行するが、より多くのメモリを消費することを示しています。 del buff
ステートメントは実行されますが、メモリを解放するものはありません。私は各ループでバッファを作成して削除しようとしましたが、同じ結果になりました。 C++でdelete x;
を実行すると、プログラムが完全にクラッシュします。SWIGで生成されたオブジェクトのメモリ管理がCに渡されました
マイガブガブ飲むインタフェースファイル:
%module example
%include "carrays.i"
%array_class(uint8_t, buffer);
%{
#include "PythonConnector.h"
%}
%include "PythonConnector.h"
Cヘッダファイル:
class PythonConnector {
public:
void print_array(uint8_t *x);
};
最小のC定義関数
void PythonConnector::print_array(uint8_t *x)
{
//int i;
//for (i = 0; i < 100; i++) {
// printf("[%d] = %d\n", i, x[i]);
//}
//delete x; // <-- This crashed the program
return;
}
テスターPythonスクリプト
import time
import example
sizeBytes = 10000
buff = example.buffer(sizeBytes)
for j in range(1000):
# Initialize data buffer
for i in range(sizeBytes):
buff[i] = i%256
buff[0] = 0
example.PythonConnector().print_array(buff.cast())
print(j)
del buff
time.sleep(10)
何か不足していますか?私は、SWIGが、バッファがガベージコレクションされていないC++に渡されるたびに、いくつかのプロキシオブジェクトを作成すると考えています。
編集:
- SWIGバージョン3.0.7
- CPythonのバージョン3.5のx64
- のWindows 10 OS
ご協力いただきありがとうございます。
私は、推測しなければならなかった場合、 'example.PythonConnector()'の繰り返し呼び出しから漏れてくると思います。あなたは本当にうまく問題を提起しました。試してみるのに必要なものはほとんどありません。あなたの例にクラス定義を追加することはできますか?私はそれが 'class PythonConnector {public:void print_array(unit8_t *); };しかし、私(または他の人たち)がこれをさらに調査する前に確認することは良いでしょう。 (SWIGとPythonのどちらのバージョンを使用していますか?) – Flexo
@Flexo私はあなたが提案した追加を行いました。また、Pythonコネクターのインスタンス化をループ外に移し(唯一インスタンス化)、魅力的に働きました。メモリは常に6MBのままです。ありがとう。 –
うまくいけば、私は今週末にそれがなぜ起こるのかを説明してくれることを願っています – Flexo