Kaynak çöp çok erken toplandı

0 Cevap php

I SWIG ve her şey çalışıyor, bir PHP uzantısı yarattık, ama yöntem çağrıları zincirleme bazı garip çöp toplama davranışlarını gözlemleyerek ediyorum. Örneğin, bu işleri:

$results = $response->results();
$row = $results->get(0)->iterator()->next();
printf('%s %s' . "\n", $row->getString(0), $row->getString(1));

Ama bu hataları seg:

$row = $response->results()->get(0)->iterator()->next();
printf('%s %s' . "\n", $row->getString(0), $row->getString(1));

Tek fark, ilk $results oluşturur, ikinci zincir aramalar sırasında birlikte.

Yudum aslında sadece PHP işlevleri ortaya çıkarır ve onlarla etkileşim PHP proxy sınıfları oluşturur. Bu proxy sınıflar temelde bu fonksiyonları normal alacağını ne olursa olsun diğer argümanlar boyunca maruz fonksiyonların her geçirilen bir kaynak tutun. Belki bu proxy sınıflar sorun olduğunu düşünerek, ben bunları atlayın ve bunun yerine doğrudan maruz işlevleri kullanmak için kodu yenilendi. Daha önce olduğu gibi, bu işleri:

$results = InvocationResponse_results($response->_cPtr);
$row = TableIterator_next(Table_iterator(Tables_get($results, 0)));
printf('%s %s' . "\n", Row_getString($row, 0), Row_getString($row, 1));

Ve yine, bu hataları seg:

$row = TableIterator_next(Table_iterator(Tables_get(InvocationResponse_results($response->_cPtr), 0)));
printf('%s %s' . "\n", Row_getString($row, 0), Row_getString($row, 1));

Yine, tek fark ilk $results oluşturur, ikinci zincir aramalar sırasında birlikte.

Bu noktada, ben gdb / valgrind içinde süre hata ayıklama geçirdi ve birlikte aramaları zincirleme InvocationResponse_results döndürür ne için yıkıcı çok erken denir belirlendi. Gözlemlemek için, ben maruz C + + fonksiyonlar ve onların Yıkıcılar üstleri de std::cout ifadeleri eklenir. Bu zincirleme olmadan çıktı:

InvocationResponse_results()
Tables_get()
Table_iterator()
TableIterator_next()
__wrap_delete_TableIterator
Row_getString()
Row_getString()
Hola Mundo
---
__wrap_delete_InvocationResponse
__wrap_delete_Row
__wrap_delete_Tables

Ben komut dosyasının yürütülmesine ve ne sonra ne sırasında ne olur ayırt edebilmek için komut sonunda --- basılmış. Hola Mundo printf arasındadır. Gerisi C + + değil. Gördüğünüz gibi, her şey beklenen sırayla çağrılır. TableIterator yıkıcı önce ben umuyordum daha denir olsa Destructors sadece betiğin yürütme sonra denir. Ancak bu herhangi bir sorun yaşanmadı ve büyük olasılıkla ilgisiz olduğunu değil. Şimdi zincirleme ile çıktı bu karşılaştırın:

InvocationResponse_results()
Tables_get()
__wrap_delete_Tables
Table_iterator()
TableIterator_next()
__wrap_delete_TableIterator
Row_getString()
Segmentation fault (core dumped)

InvocationResponse_results içine kaydedilmiş olma dönüş değeri $results, o mutlulukla yürütme bile (([{{[) (2]} arasında çağrı zincirinin dışına çıkmadan önce toplanan çöp 3)]}) ve bu hızlı sonuçta bir seg arıza giden, yolda sorunlara neden olur.

Ben de çeşitli yerlerde xdebug_debug_zval() kullanarak başvuru sayıları incelenir, ama olağandışı bir şey değil nokta. Burada zincirleme olmadan $results ve $row üzerine çıktı:

results: (refcount=1, is_ref=0)=resource(18) of type (_p_std__vectorT_voltdb__Table_t)
row: (refcount=1, is_ref=0)=resource(21) of type (_p_voltdb__Row)

Ve $row zincirleme ile:

row: (refcount=1, is_ref=0)=resource(21) of type (_p_voltdb__Row)

Ben şimdi bu birkaç gün geçirdim ve ben sadece fikirleri üzereyim, yani gerçekten bu çözme hakkında gitmek konusunda herhangi bir fikir büyük mutluluk duyacağız.

0 Cevap