簡體   English   中英

OpenCV:Python界面的內存泄漏,但C版本沒有

[英]OpenCV: memory leak with Python interface but not in the C version

我在這里問,因為到目前為止我還沒有得到OpenCV開發人員的任何幫助。 我把問題簡化為一個非常簡單的測試用例,所以可能任何有CPython背景的人都可以在這里提供幫助。

這個C代碼不泄漏:

int main() {
    while(true) {
        int hist_size[] = {40};
        float range[] = {0.0f,255.0f};
        float* ranges[] = {range};
        CvHistogram* hist = cvCreateHist(1, hist_size, CV_HIST_ARRAY, ranges, 1);
        cvReleaseHist(&hist);
    }
}

這個Python代碼確實泄漏:

while True: cv.CreateHist([40], cv.CV_HIST_ARRAY, [[0,255]], 1)

我搜索了CPython代碼(OpenCVs當前的SVN中繼代碼),發現了這個:

struct cvhistogram_t {
  PyObject_HEAD
  CvHistogram h;
  PyObject *bins;
};

...

/* cvhistogram */

static void cvhistogram_dealloc(PyObject *self)
{
  cvhistogram_t *cvh = (cvhistogram_t*)self;
  Py_DECREF(cvh->bins);
  PyObject_Del(self);
}

static PyTypeObject cvhistogram_Type = {
  PyObject_HEAD_INIT(&PyType_Type)
  0,                                      /*size*/
  MODULESTR".cvhistogram",                /*name*/
  sizeof(cvhistogram_t),                  /*basicsize*/
};

static PyObject *cvhistogram_getbins(cvhistogram_t *cvh)
{
  Py_INCREF(cvh->bins);
  return cvh->bins;
}

static PyGetSetDef cvhistogram_getseters[] = {
  {(char*)"bins", (getter)cvhistogram_getbins, (setter)NULL, (char*)"bins", NULL},
  {NULL}  /* Sentinel */
};

static void cvhistogram_specials(void)
{
  cvhistogram_Type.tp_dealloc = cvhistogram_dealloc;
  cvhistogram_Type.tp_getset = cvhistogram_getseters;
}

...

static PyObject *pycvCreateHist(PyObject *self, PyObject *args, PyObject *kw)
{
  const char *keywords[] = { "dims", "type", "ranges", "uniform", NULL };
  PyObject *dims;
  int type;
  float **ranges = NULL;
  int uniform = 1;

  if (!PyArg_ParseTupleAndKeywords(args, kw, "Oi|O&i", (char**)keywords, &dims, &type, convert_to_floatPTRPTR, (void*)&ranges, &uniform)) {
    return NULL;
  }
  cvhistogram_t *h = PyObject_NEW(cvhistogram_t, &cvhistogram_Type);
  args = Py_BuildValue("Oi", dims, CV_32FC1);
  h->bins = pycvCreateMatND(self, args);
  Py_DECREF(args);
  if (h->bins == NULL) {
    return NULL;
  }
  h->h.type = CV_HIST_MAGIC_VAL;
  if (!convert_to_CvArr(h->bins, &(h->h.bins), "bins"))
    return NULL;

  ERRWRAP(cvSetHistBinRanges(&(h->h), ranges, uniform));

  return (PyObject*)h;
}

從OpenCV C頭文件:

typedef struct CvHistogram
{
    int     type;
    CvArr*  bins;
    float   thresh[CV_MAX_DIM][2];  /* For uniform histograms.                      */
    float** thresh2;                /* For non-uniform histograms.                  */
    CvMatND mat;                    /* Embedded matrix header for array histograms. */
}
CvHistogram;

我並不完全理解所有內容,因為我之前從未使用過C接口。 但是我正在搜索的錯誤可能就是這段代碼中的某個地方。

我對嗎? 或者我應該在哪里搜索錯誤? 我該如何解決?

(注意那些看過這個問題的早期版本的人:我查看了錯誤的代碼。他們的SWIG界面已被棄用,不再使用了(但代碼仍然存在於SVN中,這就是為什么我感到困惑。所以不要看看interfaces/swig ,這段代碼很舊而且沒用過。當前的代碼存在於modules/python 。)


上游錯誤報告:OpenCV Python CreateHist中的memleak

它已被修復。

由jamesb在3周前更改

  • 狀態從接受變為關閉
  • 分辨率設置為固定

已在r4526修復

范圍參數未被釋放,並且范圍內的迭代器未被DECREF處理。 回歸現在通過,原始循環不會泄漏。

我認為你有垃圾收集問題,因為你永遠不會離開循環。

這是否更符合預期?

while True: 
    cv.CreateHist([40], cv.CV_HIST_ARRAY, [[0,255]], 1)
    cv = None

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM