1

I am developing a Object Oriented website with PHP while using some design patterns I just learnt. I have a singleton class for the Database and Some other classes which does some database operations using an instance of the Database class.

Classes,

  1. Database (singleton)
  2. User
  3. Node
  4. Sensor

class Database {
    //adaptor variable 
    private $db;

    //singleton instance
    private static $instance=NULL;

    private $config = array(
                            'host'      => 'localhost',
                            'username'  => 'XXXXXXX',
                            'password'  => '',
                            'dbname'    => 'XXX'
                            );

    private function __construct() {
        try
        {
            echo "using construct";
            //adaptor
            $this->db = new PDO('mysql:host=' . $this->config['host'] . ';dbname=' . $this->config['dbname'], $this->config['username'], $this->config['password']);
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            die($e->getMessage());
            exit();
        }
    }


    public static function getConnection()
    {
        if(self::$instance==NULL)
        {
            self::$instance = new Database();
        }
        return self::$instance;
    }

    public function prepare($sql)
    {
        return $this->db->prepare($sql);
    }
}

Other classes uses the getConnection function to get the singleton instance

class User extends Visitor {
//* has getters and setters(setters via database only)
private $db;
private $username; //*
private $email; //*
private $confirmed;//*
private $nodes;
private $id;
public function __construct() {
    $this->db = Database::getConnection();
    $argv = func_get_args();

    switch( func_num_args() ) {
        case 0: 
            self::__construct1();
            break;
        case 1:
            self::__construct2($argv[0]);
            break;
     }
}
}

So this is the basic structure of every class.

I am using singleton for the database because i don't want too many connections happening in my server which would eat up my memory.

To check whether the singleton is working properly, i have added an echo at the constructor of the database class.

So all in all, this should work properly. And it was working properly until I added some more methods to the User class(Ability to delete nodes, I have 550 lines in the user class and as I suppose, it shouldn't matter)

The error I am getting is of sort like this

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 65488 bytes) in C:\xampp\htdocs\WeatherCenter\lib\classes\Database.php on line 18

That is pointing to the config array in the database class. First I got this at my "Node" class. Then I added some

unset()

Methods into that class and then it got moved to the Database class. I am not sure why this problem is occurring, I don't have any repetitive structures in the Database class(but I have at the Node class)

ini_set('memory_limit', '-1'); is not an option since I don't want to use a way around, I need to debug the error here.

I will upload the necessary files you require,

Thanks in advance, Bhashithe

6
  • 1
    check whether something is going into infinite loop somewhere. Commented Nov 11, 2015 at 7:45
  • @bansi will do mate. checking now Commented Nov 11, 2015 at 7:50
  • @bansi there was a recursive loop underlying, i didn't see it before, stupid me. The thing is that I am checking if Users have any Nodes connected to the system. So getNodes() is a method inside User class. And then I have another method to get the owner of the Node in the Node class, Which is also a User, So when I call the User constructor, it creates another User and checks for its Nodes. This goes on forever :) Commented Nov 11, 2015 at 9:31
  • Nice to hear your problem is solved. In PHP first thing to check is for infinite loop, when you get memory exhausted error, unless you know you are going to hit memory limit. Commented Nov 11, 2015 at 9:45
  • @bansi Yes, I was checking for infinite loops in my loop structures, never imagined that it could happen in other areas too :) thanks mate! I'd answer my own question but i'd really appreciate if you could give some insight on this case, then i can mark it as correct answer Commented Nov 11, 2015 at 10:55

2 Answers 2

1

You need to find the real cause of this huge memory consumption. The line mentioned in your error message is completly misleading as most of your memory will be consumed somewhere else.

To find the critical parts of your code you could investigate memory usage by outputting something like this at appropriate places:

echo "current: " . memory_get_usage(true) . " bytes max: " . memory_get_peak_usage(true) . " bytes";

See http://php.net/manual/de/function.memory-get-usage.php

Sign up to request clarification or add additional context in comments.

3 Comments

I tried your snippet, i added it before I initialize the first object, which is of User type. It returns, current: 524288 bytes max: 524288 bytes How ever, I have some require methods before I added this, to import classes
Your claim is actually correct, I got my error in somewhere along my database class when actually it was inside another class.
The critical places to look for are typically: - fetching of database results - instantiating complex objects
0

There should be a checklist for debugging things like this.

Out of memory Error or this Allowed memory exceeded error is happening due to a infinite loop or just as the error states, you are out of dedicated memory for the task and the OS terminated your process.

What I did to debug this error is go through the program line by line and check whats happening in each and every line. You might have to take notes as well. As @maxhb pointed out, the error might not point to the exact location where the bug lies, but somewhere along the path where it went and lost its memory.

In my case there was two objects calling each other in their constructors which ultimately goes on forever creating objects inside the memory until you find that you don't have enough memory.

Lessons learned:

1 You should really stick with the class diagram and create the object oriented program.

2 you should trust what your error says, they are absolutely specific most of the time

3 recursively calling each other is never a good thing

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.