Fatal Memory Error

#1
[eluser]iFadey[/eluser]
I was doing a project in CodeIgniter and I don't know why Apache started giving me some weird kind of error :-S

Code:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 261900 bytes) in C:\wamp\www\jinnahsequaid\system\libraries\Loader.php on line 9

What I think is that maybe my models contains lots of methods. So is this happening because of that? Should I break it further in model classes? Don't think I am just using a single model for all my db operations :-P I am using one model for each db table.

Also it's my habit to free the db results after performing db operations like this:

Code:
$results->free_result();

#2
[eluser]iFadey[/eluser]
Ok now it's confirmed that it was happening because of large models (containing lot of methods in a single model and loading other models as well in the constructor).

Hmmm... it means there is some kind of memory limit in Apache configuration. Can anyone explain about this bit more?

#3
[eluser]rogierb[/eluser]
It's not apache but php, check your php.ini for memory_limit

#4
[eluser]iFadey[/eluser]
Hey thanks for the reply :-)
Sure I shall check it in php.ini.
Thanks again :-)

#5
[eluser]iFadey[/eluser]
I checked the php.ini settings using phpinfo(). It says my memory_limit is 128M. Which is far more than enough to run my scripts. I even optimized my code further and now I checked that my code requires only 256K of memory. It's still giving me the same error. Even total memory of machine is 2GB and during the execution of my scripts, still 0.88GB is free. I am really confused here. I don't know what's going on :-(

#6
[eluser]BrianDHall[/eluser]
Hm, it is kinda hard in general to get 136mb use out of PHP. What sort of things is your application doing when its throwing this? Are you dealing with images loaded into memory, or large files? Watch out for unrestrained selects (like get('table'), "SELECT *", etc, because these can easily return very large result sets.

I don't think its the models themselves doing it, as loading all of CodeIgniter takes only a few mb at most - and surely there is more of CI than you have as models?

Generally models should use lazy loading - if you are aggressively populating information, doing large selects, and storing data files in memory then its easy to start popping memory limits.

It's really hard to say without the specifics of what is happening in your application.

One thing I find odd is that the memory limit is occuring in loader - are you autoloading a bunch of models, or is this error being thrown well into your application and it just happens to be when loading something?

#7
[eluser]iFadey[/eluser]
I never select the whole table using "SELECT *". I always select using conditions.

Secondly I am not working with files at all. Only I am doing is trying to load records from the database.

I am also confused because the error is given by CI Loader class. Another thing that's confusing me is that when my scripts only require 256K of memory then how the 128M of memory exhausted?

Yes one more thing. In one of my db table, I am using mediumtext data type for storing large text. Actually one part of this application is very similar to blog. So the data type of body content is mediumtext. Is this causing the problem?

Also let me know that text, and mediumtext data types are dynamic or fixed? I mean do they take memory on the basis of characters stored in the field (just like varchar) or they just take fixed memory no matter how many characters are stored?

If no solutions will work, then I will post the code and db structure as well.

#8
[eluser]BrianDHall[/eluser]
First, get to a point before the memory errors are thrown in your script, before you start loading records. Then make use of: http://php.net/manual/en/function.memory-get-usage.php
http://php.net/manual/en/function.memory-get-usage.php
Note the 'real usage' parameter, definately check with and without toggles to see whats up.

Then walk yourself through the script and see if you can narrow down what in hell starts gobbling up memory. I would expect something sudden.

Its a good question you ask about mysql, but the problem is the error is in PHP memory - not MySQL memory usage. It's actually kind of cool how mysql handles texts and blobs, but I think unrelated as once it is given to PHP it is just a stream of data, taking up the exact space it needs regardless of how it is stored in MySQL.

Is it only on a certain page? If so, whats different about that page? If not, then it is presumably something all pages have in common.

It's like playing Sherlock Holmes.

#9
[eluser]iFadey[/eluser]
Yes you are right. I tried to change the mediumtext to text and still the same error.

I can't use that memory_get_usage() function because right now I noticed that this error occurs when I try to load a model. I realized this when I tried to use memory usage function at the beginning of my controller method (before performing any db operation). So it means it's giving the error during the loading of model class (even if I don't call a single method from that model, it's giving the same error). That's why the error occurs in Loader class.

When I comment out this statement $this->load->model( 'myModel' ); it starts working. I mean at least the page loads. After making few changes, now it's giving the same error but in different class (Base class instead of Loader)

Code:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 261900 bytes) in C:\wamp\www\jinnahsequaid\system\codeigniter\Base5.php on line 50

I think I have to show you the models. This is specially happening with 2 model classes. First is BlogPosts and second is Users.


This is the BlogPosts model class:
Code:
<?php

class BlogPosts extends Model {
    function __construct() {
        parent::Model();
        
        $this->load->database();
        
        $this->load->model( 'Users' );
        $this->load->model( 'Comments' );
        $this->load->model( 'ColAuthors' );
    }
    
    
    function countAll( $category ) {
        $this->db->where( 'category', $category );
        $this->db->where( 'status', 'active' );
        return $this->db->count_all_results( 'posts' );
    }
    
    
    function getArticleById() {
        $this->load->helper( 'MY_security_helper' );
        
        $query = 'SELECT * FROM posts WHERE id = ? AND status = \'active\' LIMIT 1';
        
        $results = $this->db->query( $query, id_clean( $this->uri->segment( 3 ) ) );
        $data = $results->row_array();
        
        if( !empty( $data ) && $data[ 'category' ] == 'Columns' ) {
            $data[ 'author_name' ] = $this->ColAuthors->getAuthorById( $data[ 'author' ] );
        }
        
        $results->free_result();
        return $data;
    }
    
    
    function getLast5Posts( $category ) {
        $query = 'SELECT * FROM posts WHERE category = ? AND status = \'active\' ORDER BY date DESC LIMIT 5';
        
        $results = $this->db->query( $query, array( $category ) );
        
        foreach( $results->result_array() as $row ) {
            $row[ 'body' ] = $this->strip_body( $row[ 'body' ] );   //add the limited version of article to the record
            //$row[ 'total_comments' ] = $this->Comments->countCommentsByPostId( $row[ 'id' ] );
            
            if( $category == 'Columns' )
                $row[ 'author_name' ] = $this->ColAuthors->getAuthorById( $row[ 'author' ] );
            
            $data[] = $row;
        }
        
        $results->free_result();
        return $data;
    }
    
    
    function getAllPosts( $category ) {
        $this->load->helper( 'MY_security_helper' );
        
        define( 'LIMIT', 10 );
        $query = 'SELECT * FROM posts WHERE category = ? AND status = \'active\' ORDER BY date DESC LIMIT ?, ' . LIMIT;
        
        $results = $this->db->query( $query, array( $category, id_clean( $this->uri->segment( 3 ) ) ) );
        
        foreach( $results->result_array() as $row ) {
            $row[ 'body' ] = $this->strip_body( $row[ 'body' ] );   //add the limited version of article to the record
            $row[ 'total_comments' ] = $this->Comments->countCommentsByPostId( $row[ 'id' ] );
            
            if( $category == 'Columns' )
                $row[ 'author_name' ] = $this->ColAuthors->getAuthorById( $row[ 'author' ] );
            
            $data[] = $row;
        }
        
        $results->free_result();
        return $data;
    }
    
    function getPostsByAuthor( $user, $category ) {
        $query = 'SELECT * FROM posts WHERE category = ? AND author = ? AND status = \'active\'';
        
        $results = $this->db->query( $query, array( $category, $user ) );
        $data = $results->result_array();
        
        $results->free_result();
        return $data;
    }
    
    
    //utility methods
    private function strip_body( $text ) {
        $body = '';
        
        foreach( explode( ' ', $text ) as $word ) {
            if( strcmp( $word, '<!--more-->' ) == 0 )
                break;
            
            $body .= $word . ' ';
        }
        
        return $body;
    }
}

#10
[eluser]iFadey[/eluser]
<b>And this is the Users model class:</b>

Code:
&lt;?php

class Users extends Model {
    function __construct() {
        parent::Model();
        
        $this->load->helper( 'MY_security_helper' );
        $this->load->helper( 'security' );
        
        $this->load->model( 'BlogPosts' );
        
        $this->load->database();
    }
    
    
    private function image_resize( $filename ) {
        $config = array(
                 'image_library' => 'gd2',
                 'source_image' => 'images/user/' . $filename,
                 'maintain_ratio' => true,
                 'height' => '100',
                 'width' => '100'
                );
        
        $this->load->library( 'image_lib', $config );
        $this->image_lib->resize();
    }
    
    private function image_upload( $username ) {
        $this->load->library( 'upload' );
        
        $config = array(
                            'upload_path' => 'images/user/',
                            'allowed_types' => 'jpg|jpeg|gif|png',
                            'max_size', '500'
                        );
        
        $this->upload->initialize( $config );
        
        if( !$this->upload->do_upload( 'img' ) ) {
            $img_name = 0;
            
            $this->session->set_flashdata( 'error', $this->upload->display_errors( '<p class="error">', '</p>' ) );
        }
        else {
            $fileInfo = $this->upload->data();
            $this->image_resize( $fileInfo[ 'file_name' ] );
            
            $img_name = $username . $fileInfo[ 'file_ext' ];
            
            rename( 'images/user/' . $fileInfo[ 'file_name' ], 'images/user/' . $img_name );
            
            $this->session->set_flashdata( 'success', 'Image uploaded successfully.' );
        }
        
        return $img_name;
    }
    
    
    function login() {
        $user = $this->input->post( 'username' );
        $pass = substr( md5( $this->input->post( 'password' ) ), 0, 254 );
        
        $query = 'SELECT username, password FROM users WHERE username = ? AND password = ? LIMIT 1';
        
        $results = $this->db->query( $query, array( $user, $pass ) );
        $data = $results->num_rows();
        
        $results->free_result();
        return $data;
    }
    
    
    function password_chk( $pass ) {
        $user = $this->session->userdata( 'user' );
        $pass = substr( md5( $pass ), 0, 254 );
        
        $query = 'SELECT username FROM users WHERE username = ? AND password = ? LIMIT 1';
        
        $results = $this->db->query( $query, array( $user, $pass ) );
        $data = $results->num_rows();
        
        $results->free_result();
        return $data;
    }
    
    
    function register() {
        $data = array();
        $data[ 'username' ] = xss_clean( trim( $this->input->post( 'user' ) ) );
        
        $data[ 'image' ] = $this->image_upload( $data[ 'username' ] );
        
        $data[ 'password' ] = substr( md5( $this->input->post( 'pass' ) ), 0, 254 );
        $data[ 'email' ] = xss_clean( trim( $this->input->post( 'email' ) ) );
        $data[ 'full_name' ] = xss_clean( $this->input->post( 'fullname' ) );
        $data[ 'about' ] = xss_clean( $this->input->post( 'about' ) );
        $data[ 'display_profile' ] = id_clean( $this->input->post( 'profile' ) );
        $data[ 'last_login' ] = strftime( '%Y-%m-%d' );
        $data[ 'articles_written' ] = 0;
        
        $this->db->insert( 'users', $data );
        return $data[ 'username' ];
    }
    
    
    function updateProfile() {
        $data = array(
                'email' => xss_clean( $this->input->post( 'email' ) ),
                'full_name' => xss_clean( $this->input->post( 'fullname' ) ),
                'about' => xss_clean( $this->input->post( 'about' ) )
            );
        
        $this->db->where( 'username', $this->session->userdata( 'user' ) );
        $this->db->update( 'users', $data );
    }
    
    
    function changePassword() {
        $password = substr( md5( $this->input->post( 'new_pass' ) ), 0, 254 );
        
        $this->db->where( 'username', $this->session->userdata( 'user' ) );
        $this->db->update( 'users', array( 'password' => $password ) );
    }
    
    
    function addPic() {
        $username = $this->session->userdata( 'user' );
        $data[ 'image' ] = $this->image_upload( $username );
        
        $this->db->where( 'username', $username );
        $this->db->update( 'users', $data );
    }
    
    
    function delPic() {
        $username = $this->session->userdata( 'user' );
        $query = 'SELECT image FROM users WHERE username = \'' . $username . '\' LIMIT 1';
        
        $results = $this->db->query( $query );
        $data = $results->row_array();
        
        if( $data[ 'image' ] ) {
            unlink( 'images/user/' . $data[ 'image' ] );
            
            $data[ 'image' ] = 0;
            $this->db->where( 'username', $username );
            $this->db->update( 'users', $data );
            
            $this->session->set_flashdata( 'success', 'Display Image deleted successfully.' );
        }
        
        $results->free_result();
    }
    
    
    function getTopAnalysts() {
        $query = 'SELECT username, articles_written FROM users WHERE status = \'active\' ORDER BY articles_written DESC LIMIT 30';
        
        $results = $this->db->query( $query );
        $data = $results->result_array();
        
        $results->free_result();
        return $data;
    }


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2021 MyBB Group.