2013-06-20 53 views
4

在該示例erlang port程序如何正確釋放一個Erlang術語

tuplep = erl_decode(buf); 
fnp = erl_element(1, tuplep); 
argp = erl_element(2, tuplep); 
... 
erl_free_compound(tuplep); 
erl_free_term(fnp); 
erl_free_term(argp); 

兩個erl_free_compound和erl_free_term用於釋放術語(和它的子項)分別相同ETERM的*。從erl_free_compund的文檔(),它說

erl_free_compound()將遞歸釋放所有與給定的Erlang項

所以相關的子項,我的問題是,不erl_element()使一個元素的副本,如果不單獨釋放會泄漏內存,否則上述情況可能會導致雙重釋放,並由erl_free_term進行檢測和處理。

+0

了快速查看erl_interface的來源,我還沒有完全圍繞它的頭部,但似乎涉及到引用計數,所以顯然erl_element增加了引用計數這通過以下erl_free_term調用來確保被刪除。或者錯過了什麼? – alienfromouterspace

回答

3

erl_interface庫確實使用了一種引用計數系統來跟蹤分配的ETERM結構的 。所以如果你寫:

ETERM *t_arr[2]; 
ETERM *t1; 

t_arr[0] = erl_mk_atom("hello"); 
t_arr[1] = erl_mk_atom("world"); 
t1 = erl_mk_tuple(&t_arr[0],2); 

你已經創建了三個(3)愛爾蘭條款(ETERM)。現在如果你調用:erl_free_term(t1),你只能釋放upp元組而不是另外兩個ETERM的 。要釋放所有分配的內存,你 得打個電話:

erl_free_term(t_arr[0]); 
erl_free_term(t_arr[1]); 
erl_free_term(t1) 

爲了避免所有這些調用erl_free_term(),您可以使用: erl_free_compund()代替。它所有ETERM都是「深」的,沒有 。所以,上面的也有來完成:

erl_free_compund(t1) 

因此,該程序能夠爲你寫的,你不必記住 到所有的子組件ETERM的引用更緊湊的方式 。 例子:

ETERM *list; 

list = erl_cons(erl_mk_int(36), 
erl_cons(erl_mk_atom("tobbe"), 
erl_mk_empty_list())); 
... /* do some work */ 
erl_free_compound(list); 

更新:要檢查是否真的釋放了所有的創造而言,你可以使用這段代碼(original manual entry

long allocated, freed; 

erl_eterm_statistics(&allocated,&freed); 
printf("currently allocated blocks: %ld\n",allocated); 
printf("length of freelist: %ld\n",freed); 

/* really free the freelist */ 
erl_eterm_release(); 

answer adopted from here

+0

感謝您回覆@WardBekker。但是這並沒有解決我最初的問題。我已經[閱讀](http://www.trapexit.org/forum/viewtopic.php?p=837&sid=7a9742f52a7d9cd46cfc6649e00d0049),並在我發佈之前進行了搜索。在我所發佈的文檔內容與trapexit中討論的內容之間,似乎存在對此的理解衝突。 – alienfromouterspace

+1

@alienfromouterspace檢查我的答案中的附加內容。希望它有幫助。從Erlang memcached客戶端的代碼https://code.google.com/p/erlangmc/source/browse/trunk/c_src/EMCPort.cpp?r=c010b97cd09111ea52d88c5529f39b381b44af74(假設它是正確的),您可以調用'erl_free_compound ()',並且不需要爲用'erl_element'創建的每個TERM調用'erl_free_term()'。 –

+0

感謝@WardBekker的這一新思路。我將寫一小段C程序構建並銷燬複雜的erlang術語,並使用erl_eterm_statistics()進行測量。這樣我就能更好地理解aparent內存泄漏場景的工作。至少它應該有助於糾正我對ETERM的理解。我會回覆我的發現。 – alienfromouterspace