- 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/
我遇到了这个错误: java.lang.IllegalArgumentException: Removing a detached instance model.student 然后我在stackov
em在中是什么意思 ... 这是从 firefox 插件 install.rdf 文件中提取的。我很好奇 em 部分添加了什么。我在 Google 上也找不到解决方案。 最佳答案 em 是包含 des
在如下所示的脚本中 create queue one create queue two create topic three 如何评论一行? 最佳答案 我可以在工具本身或文档中找到注释。 您可以做的最
谁能解释一下为什么 Redis (redis-rb) 同步驱动程序直接在 EM.synchrony block 下工作,但不在 EM:Connection 内工作? 考虑下面的例子 EM.sy
在下面,我需要得到: String regex = "Item#: .*"; String content = "xxx Item#: something yyy"; Pattern pattern
em 和 % 在文本大小调整和固定宽度站点方面有什么区别?如果我使用 em 或 % 仅用于固定宽度站点中的文本大小调整,并且正文设置为 {body:font-size:100%} 在可访问性和移动设备
这两个 CSS 语句有什么区别: h1 em { color:#ddd; } 和 h1 > em { color:#ddd; } 据我所知他们做的是完全一样的事情(虽然根据我在 W3C 上读到的第一种
在CSS3 CSS Fonts Module Level 3 (candidate Oct 13) , 在第 2.3 节中有一个对“EM 盒”的引用和一个对“EM 单元”的引用。引用如下: [The
em.find(Enity.classs, Id) em.createQuery("SELECT e From Entity e WHERE e.Id=:id") 它们是等价的吗?如果不是,它们有何不
在 CSS 中,em 是一个基于文档字体大小的相对单位。那么,如果文档本身 的字体大小以em 为单位,那么em 到底是什么?假设我们说: body { font-size: 1em; }
有实体 /** * @ORM\Entity(repositoryClass="Some\Namspace\CustomRepository") * @ORM\Table(name="image_t
您好,我有一个关于 Doctrine 的快速问题以及 merge() 和 persist() 之间的区别 我有一个 NewsBuilder 类: 这需要一个新闻实体并检查它是否存在于数据库,如果存在,
我有下面的代码,想知道 JPA 如何知道保留此更新。我预计需要 em.merge() 才能执行更新。这真的安全吗? @Stateless class User { ... public
在 JPA 中,是否保证以下片段的事务语义(=从数据库的角度来看的效果)是相同的? 片段A EntityManager em = ... List workList = ... for(Work wo
我现在正在使用 EventMachine 玩了几天,恕我直言,它的学习曲线很陡;-) 我尝试通过触发回调中需要的 HttpHeaderCrawler.query() 来返回哈希。但是在这种情况下我得到
我有以下 HTML 代码: Hello World 我正在设计它的样式: h1 {font-size:100pt} 如何将此 100pt 转换为 EM 和 REM? 最佳答案 在 CSS 中, - p
我是 OpenCV 和 C++ 的新手,我正在尝试使用 OpenCV 中的高斯混合模型构建分类器。我弄清楚了它是如何工作的,并让它工作了……也许吧。我现在得到了这样的东西: 如果我在模型训练和保存后立
我们有一个 TIBCO EMS 解决方案,它在 2-4 服务器环境中使用内置服务器故障转移。如果 TIBCO 管理员将服务从一台 EMS 服务器故障转移到另一台,则连接应该会在 EMS 服务级别自动转
YUI 中的这一行 Reset CSS给我带来了麻烦: address,caption,cite,code,dfn,em,strong,th,var { font-style: normal;
我想并发下载网页,所以我找到了这些库, 但是我分不清em-synchrony和em-http-request的关系? 我查看了每个存储库的 github,但似乎所有示例都是关于自己的, 但是从一些文章
我是一名优秀的程序员,十分优秀!