在php中的异常中使用大量内存来尝试/捕获

时间:2017-07-11 16:49:41

标签: php laravel memory

对于网站上的特定页面,我的任务是创建“表格视图”,以便网站管理员可以查看/添加/编辑/删除表格中的数据。由于我们的数据库充斥着外键,而且我对此有点新(php + laravel),我的实现如下:

  • 检查此表存在哪些外键。
  • 对于每个键:
    • 将所有表格(针对该密钥)加载到数组mapping(键/值对)
    • 浏览所有待转换的数据,并使用mapping
    • 对其进行转换
  • 返回

我这样做是为了避免多次调用db,特别是因为其他表格相对较小(因此有很多重复值)。

这是我遇到的问题:在某些情况下,在很长的范围内,我们得到了一个内存异常(即所有内存消耗)。调试后,我发现我的12 MB数据使用1.2GB内存作为峰值!我通过我的功能找出导致它的原因,并找到了罪魁祸首:

    // apply mapping to all entries

    if($changed_value == true) {
        // for $i in count(data_column). $col is the foreign key (id) in the $raw_data.
             try {
                 $final_data[$i]->{$new_col_name} = $mapping[$raw_data[$i]->{$col}];
             } catch (\Exception $e) {
                 $final_data[$i]->{$new_col_name} = $raw_data[$i]->{$col};
             }
    } 

我不希望加载时间很长,所以我没有检查映射中是否存在id,而是选择将其包装在try-catch中,如果失败则将id放入原样(即没有将id映射到值)。此循环之前的内存占用量仅为24MB,并且在此之后增加到大约240MB,但仅在捕获发生时。我通过在应用映射之前简单地检查数据是否为空来解决了这个问题,并且使用的最大内存从> 1GB到< 40MB。

我显然已经解决了这个问题,但是我不明白为什么会发生这种情况,特别是因为在下一个外键之后删除了额外的内存(最好的选择:在异常时,堆栈跟踪是存储的原因,或者是程序存储为入口点。)

至于问题:

  1. 为什么会这样?在其他可能发生的情况下,我可以事先知道它吗?

0 个答案:

没有答案