2016-11-20 7 views
0

임의의 길이의 반환 형식화 된 MemoryView 그것에 대한 수천 번의 테스트를 통해 Segmentation fault (core dumped) 오류가 발생하기 시작했습니다. 이것이 메모리 관리 문제라는 것을 알았지 만, 함수에서 반환 된 형식화 된 memoryview의 메모리를 관리하는 방법의 예제를 찾을 수 없습니다. 내가 찾은 유일한 유용한 정보는 result_arr의 수명을 파이썬 개체에 묶고 __dealloc__ 메서드를 사용하여 메모리를 확보 할 것을 권장하는 memory allocation에 있습니다.사이 썬 나는 같은 길이의 형식화 된 Memoryview를 인수로 번호 목록/입력 memoryview를 받아 반환하는 사이 썬 기능을 작성했습니다

메모리를 할당 해제하기위한 파이썬 클래스 생성을 포함하지 않는 memoryview 가비지 수집을 관리하는 방법이 있습니까?

편집 : 나는 이것을 시도하고 올바른 방식으로 메모리를 해제하는 것 같습니다.

def test(list_data): 
    cdef unsigned int n = len(list_data) 
    cdef unsigned int i = 0 
    cdef double *arr = <double*>malloc(n* sizeof(double)) 
    if not arr: 
     raise MemoryError() 
    cdef double[:] results = <double[:n]>arr 
    for i in range(n): 
     results[i] = 220 - list_data[i] 
    free(arr) 
    return results 

왜이 기능이 작동하고 더 나은 메모리 관리 방법이 있습니까?

+0

https://cython.readthedocs.io/en/stable/src/userguide/memoryviews.html#cython-arrays 및'.callback_free_data'를 참조하십시오. – DavidW

답변

0

typed memoryview는 메모리 버퍼에 대한보기를 의미하는 이름입니다. 메모리를 소유하지는 않지만 액세스하는 효율적인 방법을 제공합니다. 참조하고있는 cython 문서의 일부는 파이썬 가비지 컬렉터에 기본 힙 할당 c 배열을 묶는 방법입니다. 여기에서하는 것처럼 c 메모리 할당을 사용하려는 경우에도 책임을 져야합니다. 이것은 현재 C 레벨에서 작업하고 있기 때문에 C는 무료로 아무것도하지 않기 때문입니다. 함수는 할당 된 메모리를 보지만이를 참조하는 포인터를 버립니다. 이제이 기억은 그걸 풀어 줘야 할 책임이없는 상태로 자리 잡고 있습니다.

C의 세계로 들어가고 싶지 않다면, 파이썬에서 numpy 배열로 데이터를 읽고이 배열을 대신 cython 함수에 전달하는 것이 좋습니다. 파이썬과 numpy는 그런 종류의 일에 매우 잘 맞습니다.

그러나 malloc을 사용하려는 경우 확장 유형으로 대체 할 수 있습니다.

cdef class mymemory: 
    cdef: 
     double *arr 
     double[::1] results 

    def __cinit__(self, int n): 
     self.arr = <double*>malloc(n*sizeof(double)) 

    def __init__(self, int n): 
     self.results = <double[:n]> arr 

     """ 
     Some code for filling in the results. 
     """ 

    def __dealloc(self): 
     if self.arr != NULL: 
      free(self.arr) 

이제, mymemory가 가비지 수집되면 기본 c 배열이 해제됩니다. 그것은 당신이 그것을 요구했기 때문에 대안이지만, 나는 여전히 이것을 통해 numpy을 추천합니다.

두 번째 함수에서 메모리를 할당하고보기를 만든 다음 다시 해제하는 것처럼 보입니다. 이제이 메모리 뷰가보고있는 메모리가 더 이상 존재하지 않습니다. 그래서 당신은 정확하고, 메모리가 올바르게 해제됩니다. 그러나 이제 memoryview는 더 이상 당신을 위해 사용되지 않습니다.