草庐IT

php - 过早收集资源垃圾

coder 2024-01-01 原文

我用 SWIG 创建了一个 PHP 扩展一切正常,但我在链接方法调用时观察到一些奇怪的垃圾收集行为。例如,这有效:

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

但是这个段错误:

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

唯一的区别是第一个创建 $results,而第二个将调用链接在一起。

SWIG 实际上只是将函数暴露给 PHP,并生成 PHP 代理类来与它们交互。这些代理类基本上持有一个资源,该资源与这些函数通常采用的任何其他参数一起传递给每个公开的函数。考虑到这些代理类可能是问题所在,我重新编写了代码以绕过它们,而是直接使用公开的函数。和以前一样,这有效:

$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));

再一次,这个段错误:

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

同样,唯一的区别是第一个创建 $results,而第二个将调用链接在一起。

此时,我在 gdb/valgrind 中进行了一段时间的调试,并确定在将调用链接在一起时,InvocationResponse_results 返回的析构函数被过早调用。为了观察,我在公开的 C++ 函数及其析构函数的顶部插入了 std::cout 语句。这是没有链接的输出:

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

我在脚本末尾打印了 --- 以便能够区分脚本执行期间发生的事情和之后发生的事情。 Hola Mundo 来自 printf。其余的来自 C++。如您所见,一切都按预期顺序调用。尽管 TableIterator 析构函数的调用时间早于我的预期,但仅在脚本执行后才调用析构函数。然而,这并没有造成任何问题,而且很可能是无关的。现在将其与链接的输出进行比较:

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

如果 InvocationResponse_results 的返回值被保存到 $results 中,它会在执行甚至脱离调用链之前(在 Tables_getTable_iterator),这很快就会导致问题,最终导致段错误。

我还在各个地方使用 xdebug_debug_zval() 检查了引用计数,但没有发现任何异常。这是它在 $results$row 上的输出,没有链接:

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)

$row 上使用链接:

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

我已经在这个问题上花了几天时间,但我几乎没有想法,所以非常感谢任何关于如何解决这个问题的见解。

最佳答案

This原来是类似调试问题段错误的问题的一部分。 (Artefacto 说的)

关于php - 过早收集资源垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3526067/

有关php - 过早收集资源垃圾的更多相关文章

  1. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  2. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  3. ruby - Chef LW 资源属性默认值如何引用另一个属性? - 2

    我正在尝试将一个资源属性的默认值设置为另一个属性的值。我正在为我正在构建的tomcat说明书定义一个资源,其中包含以下定义。我想要可以独立设置的“名称”和“服务名称”属性。当未设置服务名称时,我希望它默认为为“名称”提供的任何内容。以下不符合我的预期:attribute:name,:kind_of=>String,:required=>true,:name_attribute=>trueattribute:service_name,:kind_of=>String,:default=>:name注意第二行末尾的“:default=>:name”。当我在Recipe的新block中引用我

  4. ruby - 在 Ruby 数组中收集重复项的最快/单行方法? - 2

    像这样转换数组的最快/单行方法是什么:[1,1,1,1,2,2,3,5,5,5,8,13,21,21,21]...进入像这样的对象数组:[{1=>4},{2=>2},{3=>1},{5=>3},{8=>1},{13=>1},{21=>3}] 最佳答案 要获得所需的格式,您可以附加一个调用以映射到您的解决方案:array.inject({}){|h,v|h[v]||=0;h[v]+=1;h}.map{|k,v|{k=>v}}虽然它仍然是单行的,但它开始变得凌乱了。 关于ruby-在Ruby

  5. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  6. ruby-on-rails - 为什么 Devise/Omniauth 会向 URL 添加垃圾? - 2

    使用facebook登录后,我被重定向到/#_=_,其中显示主页。这种垃圾也出现在其他URL中,例如当注册失败并被重定向到/users/sign_in#_=_为什么会发生这种情况,我该如何解决? 最佳答案 如果你真的不想要它,一些简单的javascript就可以了:if(window.location.hash=="#_=_"){window.location.hash="";} 关于ruby-on-rails-为什么Devise/Omniauth会向URL添加垃圾?,我们在StackO

  7. ruby - block 看不到方法( Chef 资源) - 2

    假设我们有两个资源:template'template1'doowner'root'group'root'endtemplate'template2'doowner'root'group'root'end我想在资源中重用代码。但是,如果我在配方中定义了一个过程,您会得到owner、group等的NoMethodError。为什么会这样?词法范围没有什么不同,是吗?因此,我必须使用self.instance_eval&common_cfg。common_cfg=Proc.new{owner'root'group'root'}template'template1'docommon_cfg.

  8. ruby-on-rails - ActionMailer HTML 编码 hell - 特殊字符替换为垃圾 - 2

    我有UTF-8字符串:Website•Facebook那是中间的一颗子弹又名•或0xE20x800xA2此值已正确存储在数据库中,并使用默认设置使用Rails3和ruby​​1.9.3正确显示在屏幕上。我正在尝试通过HTML电子邮件发送此邮件,但是当一切都说完之后,接收端看到的是垃圾:这背后的代码很简单,我有一个ActionMailer子类(默认使用UTF-8)设置以在布局中发送带有UTF-8内容编码的HTML电子邮件:email.html.erb布局文件:"all"%>内容使用与呈现网页相同的View,重要的一行是:我已经尝试了很多很多force_encoding的排列,e

  9. ruby - IO::EAGAINWaitReadable:资源暂时不可用 - 读取会阻塞 - 2

    当我尝试使用“套接字”库中的方法“read_nonblock”时出现以下错误IO::EAGAINWaitReadable:Resourcetemporarilyunavailable-readwouldblock但是当我通过终端上的IRB尝试时它工作正常如何让它读取缓冲区? 最佳答案 IgetthefollowingerrorwhenItrytousethemethod"read_nonblock"fromthe"socket"library当缓冲区中的数据未准备好时,这是预期的行为。由于异常IO::EAGAINWaitReadab

  10. ruby-on-rails - Ruby on Rails URL 中的资源映射(RESTful API) - 2

    我很难给出正确的答案,所以我会在这里征求我的问题。我正在研究RESTFulAPI。自然地,我有多种资源,其中一些由父子关系组成,一些是独立资源。我有点困难的地方是弄清楚如何让那些将根据我的API构建客户端的人更容易。情况是这样的。假设我有一个“街道”资源。每条街道都有多个住宅。SoStreet:has_manytoHomes和Homes:belongs_toStreet。如果用户想要在特定的home资源上请求HTTPGET,以下应该可行:http://mymap/streets/5/homes/10这允许用户获取ID为10的房屋的信息。直截了当。我的问题是,我授予用户访问权限是否违反了

随机推荐