我在WordPress应用程序中执行特定的PHP函数时遇到了与内存泄漏相关的问题,该函数在两个日期之间生成计划,我希望获得有关如何解决此问题的指导。
功能
该函数旨在基于两个MySQL查询和后续结果处理来获取和生成规划数据。
验证码
下面是我的代码中似乎发生内存泄漏的部分:
while ($current_date <= new DateTime($end_date)) {
// Convert the $current_date object to a string.
// $current_date_string = $current_date->format('Y-m-d H:i:s');
// Output the $current_date_string variable to the console.
// debug_to_console('$current_date : ' . $current_date_string);
if ($current_date->format('N') == $day_of_week) { // Check if current date is the correct week_day
// debug_to_console('$adjustment[$day_of_week] : ' . $adjustment[$day_of_week]);
// Check if $day_of_week is included in $adjust_occurrence and there are remaining skips
if (isset($adjust_occurrence[$day_of_week]) && $adjustment[$day_of_week] > 0) {
debug_to_console('$adjustment[$day_of_week] : ' . $adjustment[$day_of_week]);
$adjustment[$day_of_week]--; // Decrement the adjustment count
$current_date->add($interval);
continue; // move to the next while loop iteration
}
if( $current_date < $intervention_date) {
// Move to the next day within the same week if it's not the correct week_day
$current_date->add(new DateInterval('P1D'));
continue;
}else {
// Register it in the array if it is the relevant day and you don't have to skip
$new_repeat = clone $repeat;
$new_repeat->intervention_date = $current_date->format('Y-m-d');
$repeated_interventions_array[] = $new_repeat;
// Move to the next occurrence
$current_date->add($interval);
}
} else {
// Move to the next day within the same week if it's not the correct week_day
$current_date->add(new DateInterval('P1D'));
}
}
}
// filter modified array
// ... your existing code up to the nested foreach loops ...
// Your existing query to fetch modifications
$modified_repeats = $wpdb->get_results($wpdb->prepare(
"SELECT *
FROM {$wpdb->prefix}intervention_modification_reference r
WHERE r.intervenant_name = %s",
$intervenant_name
));
// Create a map for quick lookup
$intervention_map = [];
foreach ($repeated_interventions_array as $key => $repeated_intervention) {
$unique_key = $repeated_intervention->intervention_date . $repeated_intervention->start_time . $repeated_intervention->client . $repeated_intervention->intervenant_name;
$intervention_map[$unique_key] = $key;
}
// Loop through the modified repeats
foreach ($modified_repeats as $modified_repeat) {
$unique_key = $modified_repeat->intervention_date . $modified_repeat->start_time . $modified_repeat->client . $modified_repeat->intervenant_name;
if (isset($intervention_map[$unique_key])) {
$key = $intervention_map[$unique_key];
$repeated_interventions_array[$key]->intervention_date = $modified_repeat->update_intervention_date;
$repeated_interventions_array[$key]->start_time = $modified_repeat->update_start_time;
$repeated_interventions_array[$key]->duration_of_mission = $modified_repeat->update_duration_of_mission;
$repeated_interventions_array[$key]->modification = $modified_repeat->modification;
$repeated_interventions_array[$key]->mission_achieved = $modified_repeat->mission_achieved;
}
}
问题
在执行此函数时,内存使用量会显著增加,并且日志表明此功能中发生了内存泄漏。该函数处理两个主要的MySQL查询,并涉及多个循环,包括嵌套循环,用于日期计算和数据分配。
具体问题
- 嵌套循环和日期对象操作可能是内存泄漏的潜在来源。
- 对获取的MySQL数据进行内存管理,特别是在操作和将其分配给各种对象和数组时。
- 循环中DateTime和DateInterval操作的优化和内存使用。
尝试的解决方案
为了解决这个问题,我尝试实现一个哈希解决方案,以最小化嵌套循环中数据查找操作的复杂性,希望它可以减轻内存泄漏。
方法
使用哈希表:我引入了哈希表(关联数组),旨在降低嵌套循环中查找操作的时间复杂度。
最小化嵌套循环:我尝试用哈希作为键直接访问元素来代替嵌套循环操作。
内存释放:在使用大型数组和变量后,解释性地取消它们的设置,以确保PHP的垃圾收集器删除它们以释放内存。
下面是一个简单的片段来展示我的方法:
```php
$hashTable = [];
foreach ($repeat_results as $repeat) {
//... [other operations]
$key = $repeat->intervention_date . '|' . $repeat->start_time;
$hashTable[$key] = $repeat;
}
foreach ($modified_repeats as $modified_repeat) {
$key = $modified_repeat->intervention_date . '|' . $modified_repeat->start_time;
if (isset($hashTable[$key])) {
// Perform operation
$hashTable[$key]->intervention_date = $modified_repeat->update_intervention_date;
//... [other update operations]
}
}
结果
尽管有这些变化,内存泄漏问题仍然存在。虽然执行时间略有改善,但在较大的数据操作期间,该函数仍然会耗尽PHP内存。
问题
1.有人能在这段代码中找出任何潜在的内存泄漏源吗?
- PHP中是否有内存管理的最佳实践,特别是关于MySQL数据获取和处理,我可能会错过或可以更好地应用?
1.如何优化嵌套循环和日期计算,使其更高效,占用内存更少?
感谢您花时间阅读我的问题。我非常感谢任何指导、建议或资源,它们可以为我指明解决此内存泄漏问题的正确方向。
1条答案
按热度按时间pzfprimi1#
有两个明显的事情我可以看到。首先
在while循环的每次迭代中创建一个新的
DateTime
对象(当条件被测试时)。使用类似这样的代码:第二,你有:
在你的循环。每一个都导致创建一个新的
DateInterval
对象。你应该在循环外生成它:以及环路内部用途: