Welcome Guest, Not a member yet? Register   Sign In
Class referencing appears a memory leak
#1

[eluser]dyron[/eluser]
Hi,

now I'm develop for a while with CI. Nice Framework, but still some places for improvements.

After I work on a handball website, my system ran low and my browser crashed. Looking at the task manager shows me a storage allocation of 900MB! for firefox and 300MB! for apache. This isn't normal.

For debugging I created a helper which contains:
Code:
function debug()
{
  echo "<pre>\n";
  var_dump(func_get_args());
  echo "</pre>\n";
  die();
}

I used this for displaying $this. This was a experience.
Firebug notifies that this HTTP request causes 200MB traffic before arriving the PHP maximum_execution_time of 30 secs.
Most of the "$this" content was absolutely redundant, e.g. more than 50 CI_Config references.

Does anybody know, how I kept $this thin and clean?
I think it's a problem with
Code:
$CI =& get_instance();
in functions or
Code:
$this->CI =& get_instance();
in classes.

I use PHP 5, however I read & is deprecated. Should I use
Code:
$CI = get_instance();
instead?

My CI version is 1.5.4.

Anybody noticed such characteristics?

Regards dy
#2

[eluser]Pygon[/eluser]
Highly doubtful. I would suspect that you have some sort of complicated recursion or incorrectly written loop.

I've also never heard of "&" being deprecated in PHP5. In fact, quite the opposite, as PHP5 has added even more support for references (because they reduce overhead, mostly memory, compared to copies).

PHP5 added:
Code:
foreach($array as &$key => &$value)
{
//...
}
#3

[eluser]dyron[/eluser]
Hmm, I might been not correctly enough.

E_STRICT throws
Quote:Strict Standards: Assigning the return value of new by reference is deprecated in ..\system\codeigniter\Common.php on line 85

Strict Standards: Assigning the return value of new by reference is deprecated in ..\system\codeigniter\Common.php on line 91

Code:
...
85: $objects[$class] =& new $name();
...
91: $objects[$class] =& new $name();
...

So, the =& referencing is deprecated.

Am I right?
#4

[eluser]Pygon[/eluser]
No, =& is not deprecated, =& new CLASS is deprecated. There's a difference. PHP5 now defaults to pass new by reference.

This is not the cause of your problems.
#5

[eluser]dyron[/eluser]
Ok, thanks for that.

But how can I kept my $this clean? Should I need the several times nested config/language/loader/... data in this variable?

This application should run with some users without crashing the web server while wasting the resources.
200MB for every user the web server admin will thank for that :roll:
#6

[eluser]Pygon[/eluser]
As I said -- it sounds to me like your script, not CI framework, is the cause. The framework itself uses less (PHP max) than 8M. I think you need to take a closer look and debug your script.

I'm not exactly sure what you mean by the "several times nested config/language/loader". CI doesn't do this (other than in function which are immediately destroyed), so again, you should look at how you're programming things.
#7

[eluser]dyron[/eluser]
Good morning,

a half sleepless night figured out, that the multiple loading of models increases the data.

For debugging things I var_dumps $this in the calendaring class. If I call no models in the current controller, the output file is 106KB big. If I call one model, the file is 626KB and so on. Up to ~230MB for 4 model loads.
Code:
class Home extends Controller {

  function __construct()
  {
    parent::Controller();

    $this->load->library('calendar', array(...));
    $this->load->library('page', array(...));

    $this->load->model('Blog_model', 'blog');
    $this->load->model('Forums_model', 'forums');
    $this->load->model('User_model', 'users');
    $this->load->model('Match_model', 'matches');
  }
    
  function index($year = '', $month = '')
  {
  }
}

All models are based equally
Code:
class Blog_model extends Model {

  function Blog_model()
  {
    parent::Model();
  }

  ...
}

So I started logging the application init
Quote:DEBUG - 2007-11-01 08:10:01 --&gt; Config Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Hooks Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Router Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Output Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Input Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; XSS Filtering completed
DEBUG - 2007-11-01 08:10:01 --&gt; XSS Filtering completed
DEBUG - 2007-11-01 08:10:01 --&gt; Global POST and COOKIE data sanitized
DEBUG - 2007-11-01 08:10:01 --&gt; URI Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Language Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Loader Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Helpers loaded: error, lang, url
DEBUG - 2007-11-01 08:10:01 --&gt; Language file loaded: language/german/common_lang.php
DEBUG - 2007-11-01 08:10:01 --&gt; Database Driver Class Initialized
ERROR - 2007-11-01 08:10:01 --&gt; Severity: Warning --&gt; mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given ..\system\database\drivers\mysqli\mysqli_result.php 37
DEBUG - 2007-11-01 08:10:01 --&gt; Session Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Controller Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Model Class Initialized

DEBUG - 2007-11-01 08:10:01 --&gt; Config Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Hooks Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Router Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Output Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Input Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; XSS Filtering completed
DEBUG - 2007-11-01 08:10:01 --&gt; XSS Filtering completed
DEBUG - 2007-11-01 08:10:01 --&gt; Global POST and COOKIE data sanitized
DEBUG - 2007-11-01 08:10:01 --&gt; URI Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Language Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Loader Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Helpers loaded: error, lang, url
DEBUG - 2007-11-01 08:10:01 --&gt; Language file loaded: language/german/common_lang.php
DEBUG - 2007-11-01 08:10:01 --&gt; Database Driver Class Initialized
ERROR - 2007-11-01 08:10:01 --&gt; Severity: Warning --&gt; mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given ..\system\database\drivers\mysqli\mysqli_result.php 37
DEBUG - 2007-11-01 08:10:01 --&gt; Session Class Initialized
DEBUG - 2007-11-01 08:10:01 --&gt; Controller Class Initialized
DEBUG - 2007-11-01 08:10:02 --&gt; Language file loaded: language/german/calendar_lang.php
DEBUG - 2007-11-01 08:10:02 --&gt; Calendar Class Initialized

Why initialize it a second time? Which file content is necessary too?

UPDATE:
I found out, that calling
Code:
$this->CI =& get_instance();
in the page class constructor causes the second time.
#8

[eluser]dyron[/eluser]
After this issue is driving me crazy I found out that calling
Code:
$this->CI =& get_instance();
in classes increases memory space. Afterwards I replaced all of them with
Code:
$CI =& get_instance();
in each method. Even the Calendaring class uses the first one, so I was unsuspecting do this.

I dumps the variable $CI
Quote:array(1) {
[0]=>
object(Home)#10 (18) {
["_ci_scaffolding"]=>
&bool;(false)
["_ci_scaff_table"]=>
&bool;(false)
["config"]=>
&object;(CI_Config)#3 (2) {...}
["input"]=>
&object;(CI_Input)#7 (4) {...}
["benchmark"]=>
&object;(CI_Benchmark)#1 (1) {...}
["uri"]=>
&object;(CI_URI)#8 (2) {
["router"]=>
&object;(CI_Router)#5 (12) {
["config"]=>
&object;(CI_Config)#3 (2) {...} Why not point to the first CONFIG?
...
}
["output"]=>
&object;(CI_Output)#6 (4) {...}
["lang"]=>
&object;(MY_Language)#9 (3) {...}
["load"]=>
&object;(CI_Loader)#11 (11) {...}
["db"]=>
&object;(CI_DB_mysqli_driver)#12 (27) {...}
["session"]=>
&object;(CI_Session)#14 (9) {...}
["calendar"]=>
&object;(MY_Calendar)#16 (9) {...}
["layout"]=>
&object;(Layout)#18 (1) {...}
["page"]=>
&object;(Page)#17 (11) {...}
["blog"]=>
&object;(Blog_model)#21 (16) {
["_parent_name"]=>
string(10) "Blog_model"
["_ci_scaffolding"]=>
&bool;(false)
["_ci_scaff_table"]=>
&bool;(false)
["config"]=>
&object;(CI_Config)#3 (2) {...} Already existing
["input"]=>
&object;(CI_Input)#7 (4) {...} Already existing
["benchmark"]=>
&object;(CI_Benchmark)#1 (1) {...} Already existing
["uri"]=>
&object;(CI_URI)#8 (2) { Already existing
["router"]=>
&object;(CI_Router)#5 (12) { Already existing
["config"]=>
&object;(CI_Config)#3 (2) {...} ...
...}
["output"]=>
&object;(CI_Output)#6 (4) {...}
["lang"]=>
&object;(MY_Language)#9 (3) {...}
["load"]=>
&object;(CI_Loader)#11 (11) {...}
["db"]=>
&object;(CI_DB_mysqli_driver)#12 (27) {...}
["session"]=>
&object;(CI_Session)#14 (9) {...}
["calendar"]=>
&object;(MY_Calendar)#16 (9) {...}
["layout"]=>
&object;(Layout)#18 (1) {...}
["page"]=>
&object;(Page)#17 (11) {...}
["blog"]=>
&object;(Blog_model)#21 (16) {...} What the hell? A Blog_model inside the Blog_model? Phew! :gulp:
...

Any ideas?

UPDATE:
Under the shower it occurred to me, are they references? This is what I meant with "several times nested data: array(Config, Router => array(Config, []), Blog_model => array(Blog_model, []), []). okay?




Theme © iAndrew 2016 - Forum software by © MyBB