- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我编写了一个 Symfony 命令来从 API 导入一些数据。它可以工作,但问题是当我在我的数据库中插入一个大 JSON 时,我的 PHP 内存使用量会增加。每次导入事件后,我的 unitOfWork 都会增加“2”。
我已经取消了我所有使用过的对象,当你想要做大批量时,我已经阅读了 Symfony2 的文档:http://www.doctrine-project.org/blog/doctrine2-batch-processing.html
但是当我使用 $em->clear()
我的实体管理器给出了这个错误:
Notice: Undefined index: 000000007b56ea7100000000e366c259 in path-to-application\vendor\doctrine\lib\Doctrine\ORM\UnitOfWork.php line 2228
这是我的完整代码:
/**
* @see Command
*/
protected function configure() {
$this
->setName('ks:user:runkeepersync')
->setDescription('Synchroniser les activités d\'un utilisateur runkeeper')
->setDefinition(array(
new InputArgument('access_token', InputArgument::REQUIRED, 'Access token'),
))
}
/**
* @see Command
*/
protected function execute(InputInterface $input, OutputInterface $output) {
$accessToken = $input->getArgument('access_token');
$em = $this->getContainer()->get('doctrine')->getEntityManager();
$UserHasServices = $em->getRepository('KsUserBundle:UserHasServices')->findOneByToken($accessToken);
if (!is_object($UserHasServices) ) {
echo "Impossible de trouver l'utilisateur qui possède le jeton ".$accessToken."";
}
$user = $UserHasServices->getUser();
$service = $UserHasServices->getService();
echo "avant de requérir l'api : ".memory_get_usage()."\n";
try {
$rkApi = $this->getContainer()->get('ks_user.runkeeper');
$rkApi->setAccessToken($accessToken);
$activities = $rkApi->getFitnessActivities(0,25);
$nbParPages = 25;
$nomberActivitites = $activities->size;
$aActivities = $activities->items;
$nbPages = floor ($nomberActivitites/$nbParPages);
$aEndurance = array("Running", "Cycling", "Mountain Biking", "Walking", "Hiking", "Downhill Skiing", "Cross-Country Skiing", "Snowboarding", "Skating","Wheelchair", "Rowing", "Elliptical", "Other");
$aEnduranceUnderWater = array("Swimming");
$enduranceOnEarthType = $em->getRepository('KsActivityBundle:SportType')->findOneByLabel("endurance");
if (!is_object($enduranceOnEarthType) ) {
echo "Impossible de trouver le type de sport d'endurance";
}
$enduranceUnderWaterType = $em->getRepository('KsActivityBundle:SportType')->findOneByLabel("endurance_under_water");
if (!is_object($enduranceUnderWaterType) ) {
echo "Impossible de trouver le type de sport d'endurance sous l'eau ";
}
echo "Après avoir récupéré 25 activités : ".memory_get_usage()."\n";
$a = 0;
for($i=0;$i<=$nbPages;$i++){
if($i!=0){
$activities = $rkApi->getFitnessActivities($i,25);
$aActivities = $activities->items;
}
foreach ($aActivities as $activity) {
$a = $a+1;
$codeSport = $this->formatNameSport($activity->type);
$sport = $em->getRepository('KsActivityBundle:Sport')->findOneByCodeSport($codeSport);
if (!is_object($sport) ) {
$sport = new \Ks\ActivityBundle\Entity\Sport();
$sport->setLabel($codeSport);
$sport->setCodeSport($codeSport);
$sport->setSportType($enduranceOnEarthType);
$em->persist($sport);
$em->flush();
}
$activityDetail = json_decode($rkApi->requestJSONHealthGraph($activity->uri));
if(in_array($activity->type, $aEndurance)){
$urlActivitieDetail = $activityDetail->activity;
$ActivitySessionEnduranceOnEarth = new \Ks\ActivityBundle\Entity\ActivitySessionEnduranceOnEarth($user);
isset($activity->total_distance)? $ActivitySessionEnduranceOnEarth->setDistance($activity->total_distance) : "";
isset($activity->duration)? $ActivitySessionEnduranceOnEarth->setDuration($this->secondesToTimeDuration($activity->duration)) : "";
isset($activity->start_time)? $ActivitySessionEnduranceOnEarth->setIssuedAt(new \DateTime($activity->start_time)) : "";
$ActivitySessionEnduranceOnEarth->setModifiedAt(new \DateTime('Now'));
$ActivitySessionEnduranceOnEarth->setSport($sport);
isset($activityDetail->total_calories)? $ActivitySessionEnduranceOnEarth->setCalories($activityDetail->total_calories) : "";
isset($activityDetail->climb)? $ActivitySessionEnduranceOnEarth->setElevationGain($activityDetail->climb) : "";
$maxElevation = 0;
$minElevation = 10000;
if(isset($activityDetail->path)){
foreach($activityDetail->path as $gpsPoint){
if($gpsPoint->altitude > $maxElevation){
$maxElevation = $gpsPoint->altitude;
}
if($gpsPoint->altitude < $minElevation){
$minElevation = $gpsPoint->altitude;
}
}
$ActivitySessionEnduranceOnEarth->setElevationMin($minElevation);
$ActivitySessionEnduranceOnEarth->setElevationMax($maxElevation);
}
$em->persist($ActivitySessionEnduranceOnEarth);
$em->flush();
//Pour chaque activité on a un identifiant relatif au service qu'on synchronise
$ActivityComeFromService = new \Ks\ActivityBundle\Entity\ActivityComeFromService();
$ActivityComeFromService->setActivity($ActivitySessionEnduranceOnEarth);
$ActivityComeFromService->setService($service);
$ActivityComeFromService->setIdWebsiteActivityService($activity->uri);
$ActivityComeFromService->setSourceDetailsActivity($rkApi->requestJSONHealthGraph($activity->uri));
$ActivityComeFromService->setTypeSource("JSON");
$em->persist($ActivityComeFromService);
$em->flush();
echo "Import de l'activite num ".$a." type :".$activity->type." effectue avec success \n";
unset($ActivitySessionEnduranceOnEarth);
unset($ActivityComeFromService);
echo "UnitOFWOrk -> ".$em->getUnitOfWork()->size()."\n";
}
if(in_array($activity->type, $aEnduranceUnderWater)){
$ActivitySessionEnduranceUnderWater = new \Ks\ActivityBundle\Entity\ActivitySessionEnduranceUnderWater($user);
isset($activity->total_distance)? $ActivitySessionEnduranceUnderWater->setDistance($activity->total_distance) : "";
isset($activity->duration)? $ActivitySessionEnduranceUnderWater->setDuration($this->secondesToTimeDuration($activity->duration)) : "";
isset($activity->start_time) && !empty($activity->start_time)? $ActivitySessionEnduranceUnderWater->setIssuedAt(new \DateTime($activity->start_time)) : "";
$ActivitySessionEnduranceUnderWater->setModifiedAt(new \DateTime('Now'));
$ActivitySessionEnduranceUnderWater->setSport($sport);
isset($activityDetail->total_calories)? $ActivitySessionEnduranceUnderWater->setCalories($activityDetail->total_calories) : "";
isset($activityDetail->notes)? $ActivitySessionEnduranceUnderWater->setDescription($activityDetail->notes) : "";
$em->persist($ActivitySessionEnduranceUnderWater);
$em->flush();
$ActivityComeFromService = new \Ks\ActivityBundle\Entity\ActivityComeFromService();
$ActivityComeFromService->setActivity($ActivitySessionEnduranceUnderWater);
$ActivityComeFromService->setService($service);
$ActivityComeFromService->setIdWebsiteActivityService($activity->uri);
$ActivityComeFromService->setSourceDetailsActivity($rkApi->requestJSONHealthGraph($activity->uri));
$ActivityComeFromService->setTypeSource("JSON");
$em->persist($ActivityComeFromService);
$em->flush();
echo "Import de l'activité num ".$a." type :".$activity->type." effectué avec succès\n";
unset($ActivitySessionEnduranceUnderWater);
unset($ActivityComeFromService);
}
echo "Après chaque activité : ".memory_get_usage()."\n";
unset($sport);
unset($activityDetail);
$em->clear();
}
}
} catch (\Exception $e) {
throw $e;
}
}
谢谢,@AdrienBrault。我用--env=prod --no-debug
测试过,确实是消耗的内存少了,但是内存还是增加了。我怎样才能真正清除实体管理器?并稳定内存?
最佳答案
Symfony 在开发环境中记录所有的 SQL 查询,所以首先你需要禁用它
// disable logger
$em->getConnection()->getConfiguration()->setSQLLogger(null);
您可以在实体上使用事件监听器,这也可能会增加内存使用量。您可以像这样禁用它们
// remove all listeners
foreach ($em->getEventManager()->getListeners() as $event => $listeners) {
foreach ($listeners as $listener) {
$em->getEventManager()->removeEventListener($event, $listener);
}
}
从您的代码中删除 unset
,不需要它们,因为您在循环的每一步都清除了实体管理器。
// save and clear
$em->flush();
$em->getUnitOfWork()->clear();
请记住,如果您将查询分组到一个 flush
中,原则可以优化您的查询并提高性能。因此,最佳做法是对数据的某些部分执行一次 flush
。例如:
// collect 100 entities and then save them
if (($i % 100) == 0) {
$em->flush();
$em->getUnitOfWork()->clear();
}
关于php - Symfony2 中 $em->clear() 的未定义索引错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11392931/
这几天我一直在努力。我一直在自学 CSS,所以对菜鸟好一点。我正在创建一个推荐 slider 。推荐以 3 个 block 显示。我希望前 2 个下降,第 3 个上升。但是当 slider 激活时,无
我最近开始学习 Nodejs,现在我很困惑我的网络应用程序使用什么,html 还是 ejs (Express)。 Ejs 使用 Express 模块,而 .html 使用 HTML 模块。我的第一个问
假设我们有一个 PostgreSQL 表contacts,每条记录都有一堆带标签的电子邮件地址(标签和电子邮件对)——其中一个是“主要”。 存储方式如下: id 主键 电子邮件 文本 email_la
我成功为一种新的tesseract语言编写了traineddata文件,但是当我完成时,我继续收到以下错误: index >= 0 && index = 0 && 索引 < size_used_ :E
这个问题已经有答案了: How to deal with SettingWithCopyWarning in Pandas (21 个回答) 已关闭 4 年前。 假设我有一个像这样的数据框,第一列“密
如果我有一个位置或行/列同时用于 A 和 B 位置,请检查 B 是否与 A 成对角线? 1 2 3 4 5 6 7 8 9 例如,我如何检查 5 是否与 7 成对角线? 此外,如果我检查 4 是
MongoDB:索引 一、 创建索引 默认情况下,集合中的_id字段就是索引,我们可以通过getIndexes()方法来查看一个集合中的索引 > db.user.getIndexes() [ { "v
一、索引介绍 索引是一种用来快速查询数据的数据结构。 B+Tree就是一种常用的数据库索引数据结构,MongoDB采用B+Tree 做索引,索引创建在colletions上。 MongoDB不使用索引
我无法决定索引。 就像我有下面的查询需要太多时间来执行: select count(rn.NODE_ID) as Count, rnl.[ISO_COUNTRY_CODE] as Cou
我有这些表: CREATE TABLE `cstat` ( `id_cstat` bigint(20) NOT NULL, `lang_code` varchar(3) NOT NULL,
我正在尝试找到一种方法来提高包含 IP 范围的 mysql 表的性能(在高峰时段每秒最多有 500 个 SELECT 查询(!),所以我有点担心)。 我有一个这种结构的表: id smallint(
jquery index() 似乎无法识别元素之一,总是说“无法读取未定义的属性‘长度’”这是我的代码。mnumber 是导致问题的原因。我需要 number 和 mnumber 才能跟踪使用鼠标,并
我们有一个包含近 4000 万条记录的 MongoDB 集合。该集合的当前大小为 5GB。此集合中存储的数据包含以下字段: _id: "MongoDB id" userid: "user id" (i
文档说:如果你有多个字段的复合索引,你可以用它来查询字段的开始子集。所以如果你有一个索引一个,乙,丙你可以用它查询一种一个,乙a,b,c 我的问题是,如果我有一个像这样的复合索引一个,乙,丙我可以查询
我正在使用 $('#list option').each(function(){ //do stuff }); 循环列表中的选项。我想知道如何获取当前循环的索引? 因为我不想让 var i = 0;循
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL
SQLite 索引(Index) 索引(Index)是一种特殊的查找表,数据库搜索引擎用来加快数据检索。简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书后边的索引是非常相似的。
我是 RavenDB 的新手。我正在尝试使用多 map 索引功能,但我不确定这是否是解决我的问题的最佳方法。所以我有三个文件:Unit、Car、People。 汽车文件看起来像这样: { Id: "
我有以下数据,我想根据范围在另一个表中建立索引 我想要实现的是,例如,如果三星的销售额为 2500,则折扣为 2%,低于 3000 且高于 1000 我知道它可以通过索引来完成,与多个数组匹配,然后指
我正在检查并删除 SQL 数据库中的重复和冗余索引。 所以如果我有两个相同的索引,我会删除。 例如,如果我删除了重叠的索引... 索引1:品牌、型号 指标二:品牌、型号、价格 我删除索引 1。 相同顺
我是一名优秀的程序员,十分优秀!