如何在循环中“释放”内存?

时间:2011-09-09 20:01:55

标签: php mysql memory-management soap memory-leaks

我有一个在共享托管环境中运行的脚本,我无法更改可用的PHP内存量。该脚本通过soap使用Web服务。我无法立即获取所有数据,或者内存不足,因此我在mysql数据库本地缓存数据方面取得了一些成功,以便后续查询更快。

基本上我没有查询Web服务5个月的数据,而是一次查询它1个月并将其存储在mysql表中并检索下个月等。这通常有效但我有时仍会耗尽内存。

我的基本代码逻辑是这样的:

  1. 使用soap连接到Web服务;
  2. 连接到mysql数据库
  3. 查询网络服务并将结果存储在变量$ results;
  4. 将$ results转换为mysql表
  5. 为每个月的数据重复步骤3和4
  6. 在每次迭代中使用相同的变量,所以我假设来自Web服务的每批结果都会覆盖以前的内存?我尝试在迭代之间使用unset($ results)但是没有做任何事情。我每次输出与memory_get_usage(true)一起使用的内存,并且每次迭代都会增加使用的内存。

    我有什么想法可以解决这个内存泄漏问题?如果我不够清楚,请发表评论,我可以提供更多细节。谢谢!

    *** EDIT

    这是一些代码(我使用nusoap而不是php5原生肥皂客户端,如果这有所不同):

    $startingDate = strtotime("3/1/2011");
    $endingDate = strtotime("7/31/2011");
    // connect to database
    mysql_connect("dbhost.com", "dbusername" "dbpassword");
    mysql_select_db("dbname");
    // configure nusoap
    $serverpath ='http://path.to/wsdl';
    $client = new nusoap_client($serverpath);
    // cache soap results locally
    while($startingDate<=$endingDate) {
        $sql = "SELECT * FROM table WHERE date >= ".date('Y-m-d', $startingDate)." AND date <= ".date('Y-m-d', strtotime($startingDate.' +1 month'));
        $soapResult = $client->call('SelectData', $sql);
        foreach($soapResult['SelectDateResult']['Result']['Row'] as $row) {
            foreach($row as &$data) {
                $data = mysql_real_escape_string($data);
            }
            $sql = "INSERT INTO table VALUES('".$row['dataOne']."', '".$row['dataTwo']."', '".$row['dataThree'].")";
            $mysqlResults = mysql_query($sql);
        }
        $startingDate = strtotime($startingDate." +1 month");
        echo memory_get_usage(true); // MEMORY INCREASES EACH ITERATION
    }
    

2 个答案:

答案 0 :(得分:5)

解决了它。至少部分。使用nusoap存在内存泄漏。 Nusoap将调试日志写入$ GLOBALS变量。在nusoap.php中改变这一行可以释放大量内存。

变化

$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;

$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 0;

我更喜欢使用php5的本机soap客户端,但我得到了一些奇怪的结果,我认为这些结果特定于我想要使用的web服务。如果有人熟悉使用php5的soap客户端和www.mindbodyonline.com的SOAP API,请告诉我。

答案 1 :(得分:-1)

您是否曾在$ startingDate上尝试unset()而在$ mysqlResults上尝试mysql_free_result()

即使这不是问题,SELECT *也不赞成。

编辑:也许也释放SOAP结果。一些简单的东西开始,看看是否有帮助。