我有一个脚本,它将803 * 803 (644 809)图表中的每个值分别设置为1 000 000。使用~500 * 500一切正常 - 但现在它崩溃了 - 它试图分配超过64MB的内存(我没有)。解决方案是什么?不知何故“拆分”或......?
$result=mysql_query("SELECT * FROM some_table", $connection);
confirm($result);
while($rows = mysql_fetch_array($result)){
$result2=mysql_query("SELECT * FROM some_table", $connection);
confirm($result2);
while($rows2 = mysql_fetch_array($result2)){
$first = $rows["something"];
$second = $rows2["something2"];
$graph[$first][$second] = 1000000;
}
}
*它是关于Dijkstra算法
P.S。不,我不能分配超过64MB
答案 0 :(得分:3)
尝试在每个循环结束时使用mysql_free_result($result2);
释放内部sql结果,PHP脚本可能不会为您执行此操作,具体取决于PHP版本(垃圾收集器可能未启用或可能无用)由于PHP版本太旧了。)
不要在循环中实现两个临时变量,直接使用mysql_fetch_array结果,如$graph[$rows["something"]][$rows2["something2"]] = 1000000;
,每个循环将节省2个内存分配..
PS:这是 micro - 优化,因此它可以帮助您节省足够的内存以适应您的64M内存。不要忘记,对于64 * 1024 * 1024字节的内存,每个644 809元素的最大大小平均为104字节,加上数组大小本身,以及您为算法分配的其余临时数据
如果它不合适,请考虑拆分矩阵并执行批量作业等,以便在较少的内存消耗中分割您的工作,但运行多个脚本。
答案 1 :(得分:1)
如果您的上述代码示例实际上与您的实际代码匹配,那么您将获取相同的结果两次(即使在循环中也是第二个)。如果它是相同的数据集,那么从数据库中获取一次就足够了,这将完全减少数据库负载,执行时间和内存占用。
也许以下方法可能会在您的内存限制环境中起作用。
$result = mysql_unbuffered_query("SELECT * FROM some_table", $connection);
confirm($result);
$rawData = array();
while ($rows = mysql_fetch_assoc($result)) {
$rawData[] = array($rows["something"], $rows["something2"]);
}
mysql_free_result($result);
$graph = array();
foreach ($rawData as $r1) {
foreach ($rawData as $r2) {
$graph[$r1[0]][$r2[1]] = 1000000;
}
}
unset($rawData);
注意:
mysql_fetch_assoc()
而不是mysql_fetch_array()
,因为后者将每列返回两次(一个数字索引,一个按列名索引)mysql_unbuffered_query()
代替mysql_query()
也可能会减少内存占用量(取决于实际的数据集大小)答案 2 :(得分:0)
尝试使用http://en.wikipedia.org/wiki/Adjacency_list来表示图形而不是邻接矩阵(我认为您使用的是$graph[$first][$second] = 1000000;
对于稀疏图形,它占用的内存较少。
答案 3 :(得分:0)
如果你坚持使用PHP进行高内存操作(开始时这不是一个好主意),我会将图形划分为象限,并使用GD来组合象限。这样,您只需构建内存占用量为1/4的图形。
同样,这并不理想,但你正试图用钉子钉锤子:D