学说水合作用期间的分段错误 - 如何调试?
Segmentation faults during doctrine hydration - how to debug?
我正在 运行ning 一个控制台命令,它获取一种类型的所有实体(并从中读取一些数据)。
$q = $this->em->createQuery(/** @lang DQL */'select u from App\Entity\DataSample u order by u.creationDate ASC');
两种迭代策略:
foreach ($q->getResult() as $d) {
}
和
$iterableResult = $q->iterate();
foreach ($iterableResult as $onerow) {
/* @var $d DataSample */
$d = $onerow[0];
}
导致分段错误!
请注意,我实际上在循环内什么也没做!
第二个循环执行 运行 几万次迭代,然后出现段错误,第一个循环在 getResult()
期间出现段错误。
还有足够的可用内存,程序在大约 200 MB 内存使用时中断。
我的 xdebug trace 对我没有太大帮助,它结束如下:
240.2365 489614864 -> str_pad() /var/www/rrr/vendor/ramsey/uuid/src/Codec/StringCodec.php:167
240.2365 489614904 -> Ramsey\Uuid\Builder\DefaultUuidBuilder->build() /var/www/rrr/vendor/ramsey/uuid/src/Codec/StringCodec.php:84
240.2365 489615000 -> Ramsey\Uuid\Uuid->__construct() /var/www/rrr/vendor/ramsey/uuid/src/Builder/DefaultUuidBuilder.php:52
240.2365 489614448 -> Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateColumnInfo() /var/www/rrr/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:270
240.2365 489614448 -> Ramsey\Uuid\Doctrine\UuidType->convertToPHPValue() /var/www/rrr/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:315
我检查了相应 table 中的所有 (ramsey/uuid) 个 ID,并且 Uuid::isValid()
中的所有 return 为真
有趣的事实:输出所有id时,我发现它总是发生在同一个DataSample!?
好的,我找到了 "solution":
我每 100 次迭代插入对 $em->clear()
和 gc_collect_cycles
的调用,现在它终止了(实际上速度更快!)。
$i = 0;
$iterableResult = $q->iterate();
foreach ($iterableResult as $onerow) {
/* @var $d DataSample */
$d = $onerow[0];
if($i % 100 === 0){
$this->em->clear();
gc_collect_cycles();
}
$i++;
}
但显然,这只适用于 iterableResult,使用 getResult
理论上也应该有效??
我正在 运行ning 一个控制台命令,它获取一种类型的所有实体(并从中读取一些数据)。
$q = $this->em->createQuery(/** @lang DQL */'select u from App\Entity\DataSample u order by u.creationDate ASC');
两种迭代策略:
foreach ($q->getResult() as $d) {
}
和
$iterableResult = $q->iterate();
foreach ($iterableResult as $onerow) {
/* @var $d DataSample */
$d = $onerow[0];
}
导致分段错误!
请注意,我实际上在循环内什么也没做!
第二个循环执行 运行 几万次迭代,然后出现段错误,第一个循环在 getResult()
期间出现段错误。
还有足够的可用内存,程序在大约 200 MB 内存使用时中断。
我的 xdebug trace 对我没有太大帮助,它结束如下:
240.2365 489614864 -> str_pad() /var/www/rrr/vendor/ramsey/uuid/src/Codec/StringCodec.php:167
240.2365 489614904 -> Ramsey\Uuid\Builder\DefaultUuidBuilder->build() /var/www/rrr/vendor/ramsey/uuid/src/Codec/StringCodec.php:84
240.2365 489615000 -> Ramsey\Uuid\Uuid->__construct() /var/www/rrr/vendor/ramsey/uuid/src/Builder/DefaultUuidBuilder.php:52
240.2365 489614448 -> Doctrine\ORM\Internal\Hydration\ObjectHydrator->hydrateColumnInfo() /var/www/rrr/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:270
240.2365 489614448 -> Ramsey\Uuid\Doctrine\UuidType->convertToPHPValue() /var/www/rrr/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:315
我检查了相应 table 中的所有 (ramsey/uuid) 个 ID,并且 Uuid::isValid()
有趣的事实:输出所有id时,我发现它总是发生在同一个DataSample!?
好的,我找到了 "solution":
我每 100 次迭代插入对 $em->clear()
和 gc_collect_cycles
的调用,现在它终止了(实际上速度更快!)。
$i = 0;
$iterableResult = $q->iterate();
foreach ($iterableResult as $onerow) {
/* @var $d DataSample */
$d = $onerow[0];
if($i % 100 === 0){
$this->em->clear();
gc_collect_cycles();
}
$i++;
}
但显然,这只适用于 iterableResult,使用 getResult
理论上也应该有效??