Php array memory usage

Simple Memory Management Tips In PHP (With Examples)

Welcome to a quick tutorial on memory management in PHP. Running out of memory from massive scripts? While the easy way is to install more memory into the server, I am pretty sure that is not the most efficient way.

We can do simple memory management in PHP, without any complex tools.

  • Use memory_get_peak_usage() to track peak memory usage.
  • Apply some changes to improve the script efficiency.
    • Do not read entire files at once, read line-by-line.
    • Do not fetch all entries from the database at once, fetch one-by-one.
    • Use unset($VAR) to manually remove unused variables, and gc_collect_cycles() to activate the garbage collector.
    • Reduce the number of temporary variables and dependency on third-party libraries.

    That’s all. No “special tools” nor “advanced techniques” are required, just some simple changes to the script – Read on for the examples!

    TLDR – QUICK SLIDES

    Simple PHP Memory Management

    TABLE OF CONTENTS

    PHP MEMORY PERFORMANCE TRACKING

    For this first section, let us walk through how to track memory usage and execution time – No special tools are required.

    A) TRACK MEMORY USAGE

     // (B) MEMORY USAGE WITH ARRAY IN MEMORY echo "WITH LARGE ARRAY IN MEMORY
    "; echo "Current usage: " . memory_get_usage() . " bytes
    "; echo "Peak usage: " . memory_get_peak_usage() . " bytes

    "; // (C) MEMORY USAGE AFTER ARRAY IS REMOVED unset($arr); echo "AFTER ARRAY IS REMOVED
    "; echo "Current usage: " . memory_get_usage() . " bytes
    "; echo "Peak usage: " . memory_get_peak_usage() . " bytes";

    On my computer, the output is:

    WITH LARGE ARRAY IN MEMORY Current usage: 6683280 bytes Peak usage: 6683360 bytes AFTER ARRAY IS REMOVED Current usage: 391744 bytes Peak usage: 6683360 bytes
    • memory_get_usage() returns the current memory usage, at the specified line of the script.
    • memory_get_peak_usage() returns the highest recorded memory usage, at the specified line of the script.

    For the purpose of memory tracking, memory_get_peak_usage() will probably make more sense.

    B) TIME TAKEN TO EXECUTE

     // (C) TOTAL TIME TAKEN $time = microtime(true) - $time; echo "Time taken - $time secs"; 

    Yes, this is not tracking memory usage but is an important metric nonetheless. We do not want a massive script to hog a huge chunk of memory for extended periods of time.

    TRACKING WITH TOOLS

    No “special tools” are required for performance tracking. But if you prefer “something advanced”, check out Xdebug.

    PHP MEMORY EFFICIENT CODING

    Now that we have eyes on memory usage and execution time, the next step is to improve the efficiency of the scripts. Here are a few simple tips to reduce memory usage.

    1) READ LINE-BY-LINE FROM THE DATABASE

     PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); // (C) PREPARE SQL $stmt = $pdo->prepare("SELECT * FROM `TABLE`"); $stmt->execute(); // (D) BAD - FETCH ALL AT ONCE // $results = $stmt->fetchAll(); // foreach ($results as $r) < print_r($r); >// (E) PREFERRED - FETCH LINE-BY-LINE while ($r = $stmt->fetch()) < print_r($r); >// (F) CLOSE DATABASE CONNECTION if ($stmt !== null) < $stmt = null; >if ($pdo !== null) < $pdo = null; >// (G) PEAK MEMORY USED echo "PEAK USAGE - " . memory_get_peak_usage();

    Need to output a huge list of records into HTML or to a document? Don’t fetch them all at once. Fetch and deal with the records one by one instead.

    2) READ FILE LINE-BY-LINE

     fclose($handle); // (D) PEAK MEMORY USED echo "PEAK USAGE - " . memory_get_peak_usage();

    Same old story, don’t read a massive file into a single string at once. Read line-by-line instead.

    3) REMOVE USELESS VARIABLES

    Some of you code ninjas may laugh and brush this aside as “trivial”. How much memory can a single variable take? Well, the more useless variables you have floating around, the more memory the script consumes. Remove hundreds of such useless flags and variables in a huge project, and you will see a huge difference.

    4) MANUALLY REMOVE TEMPORARY VARIABLES

    Temporary flags, variables, arrays, and objects – We can manually remove them to reduce resource hogging. Garbage collection is quite smart in PHP, but we can also call gc_collect_cycles() to clear things up.

    5) DIRECT OUTPUT FROM THE DATABASE

     PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); // (C) HTTP HEADERS header("Content-Type: application/octet-stream"); header("Content-Transfer-Encoding: Binary"); header("Content-disposition: attachment; filename=\"export.csv\""); // (D) PREPARE SQL $stmt = $pdo->prepare("SELECT * FROM `TABLE`"); $stmt->execute(); // (E) BAD - FETCH ALL AT ONCE // $results = $stmt->fetchAll(); // foreach ($results as $r) < echo implode(",", $r) . "\r\n"; >// (F) PREFERRED - FETCH & DIRECTLY OUTPUT while ($r = $stmt->fetch()) < echo implode(",", $r) . "\r\n"; >// (G) CLOSE DATABASE CONNECTION if ($stmt !== null) < $stmt = null; >if ($pdo !== null)

    Remember the “read line-by-line” example earlier? This is kind of a follow-up. If you are creating a CSV file or outputting to HTML – Just directly output the records. Don’t need to go the roundabout way of fetching the all rows into a massive array first, then use a for loop to run through them.

    DOWNLOAD & NOTES

    Here is the download link to the example code, so you don’t have to copy-paste everything.

    SUPPORT

    600+ free tutorials & projects on Code Boxx and still growing. I insist on not turning Code Boxx into a «paid scripts and courses» business, so every little bit of support helps.

    EXAMPLE CODE DOWNLOAD

    Click here for the source code on GitHub gist, just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

    That’s all for this guide, and here is a small section on some links that may be useful to you.

    SETTING THE MEMORY LIMIT

    If all else fails, the only way is to raise the memory limits in php.ini .

    Or we can also set it in the script during runtime.

    INFOGRAPHIC CHEAT SHEET

    THE END

    Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

    Leave a Comment Cancel Reply

    Breakthrough Javascript

    Take pictures with the webcam, voice commands, video calls, GPS, NFC. Yes, all possible with Javascript — Check out Breakthrough Javascript!

    Socials

    About Me

    W.S. Toh is a senior web developer and SEO practitioner with over 20 years of experience. Graduated from the University of London. When not secretly being an evil tech ninja, he enjoys photography and working on DIY projects.

    Code Boxx participates in the eBay Partner Network, an affiliate program designed for sites to earn commission fees by linking to ebay.com. We also participate in affiliate programs with Bluehost, ShareASale, Clickbank, and other sites. We are compensated for referring traffic.

    Источник

    memory_get_usage

    Returns the amount of memory, in bytes, that’s currently being allocated to your PHP script.

    Parameters

    Set this to true to get total memory allocated from system, including unused pages. If not set or false only the used memory is reported.

    Note:

    PHP does not track memory that is not allocated by emalloc()

    Return Values

    Returns the memory amount in bytes.

    Examples

    Example #1 A memory_get_usage() example

    // This is only an example, the numbers below will
    // differ depending on your system

    echo memory_get_usage () . «\n» ; // 36640

    $a = str_repeat ( «Hello» , 4242 );

    echo memory_get_usage () . «\n» ; // 57960

    echo memory_get_usage () . «\n» ; // 36744

    See Also

    User Contributed Notes 15 notes

    To get the memory usage in KB or MB

    function convert ( $size )
    $unit =array( ‘b’ , ‘kb’ , ‘mb’ , ‘gb’ , ‘tb’ , ‘pb’ );
    return @ round ( $size / pow ( 1024 ,( $i = floor ( log ( $size , 1024 )))), 2 ). ‘ ‘ . $unit [ $i ];
    >

    echo convert ( memory_get_usage ( true )); // 123 kb
    ?>

    Note, that the official IEC-prefix for kilobyte, megabyte and so on are KiB, MiB, TiB and so on.

    At first glance this may sound like «What the hell? Everybody knows, that we mean 1024 not 1000 and the difference is not too big, so what?». But in about 10 years, the size of harddisks (and files on them) reaches the petabyte-limit and then the difference between PB and PiB is magnificent.

    Better to get used to it now. 🙂

    memory_get_usage() is used to retrieve the memory allocated to PHP only (or your running script). But intuitively, many people expect to get the memory usage of the system, based on the name of the function.

    So if you need the overall memory usage, following function might be helpful. If retrieves the memory usage either in percent (without the percent sign) or in bytes by returning an array with free and overall memory of your system. Tested with Windows (7) and Linux (on an Raspberry Pi 2):

    // Returns used memory (either in percent (without percent sign) or free and overall in bytes)
    function getServerMemoryUsage ( $getPercentage = true )
    $memoryTotal = null ;
    $memoryFree = null ;

    if ( stristr ( PHP_OS , «win» )) // Get total physical memory (this is in bytes)
    $cmd = «wmic ComputerSystem get TotalPhysicalMemory» ;
    @ exec ( $cmd , $outputTotalPhysicalMemory );

    // Get free physical memory (this is in kibibytes!)
    $cmd = «wmic OS get FreePhysicalMemory» ;
    @ exec ( $cmd , $outputFreePhysicalMemory );

    // Find free value
    foreach ( $outputFreePhysicalMemory as $line ) if ( $line && preg_match ( «/^4+\$/» , $line )) $memoryFree = $line ;
    $memoryFree *= 1024 ; // convert from kibibytes to bytes
    break;
    >
    >
    >
    >
    else
    if ( is_readable ( «/proc/meminfo» ))
    $stats = @ file_get_contents ( «/proc/meminfo» );

    if ( $stats !== false ) // Separate lines
    $stats = str_replace (array( «\r\n» , «\n\r» , «\r» ), «\n» , $stats );
    $stats = explode ( «\n» , $stats );

    // Separate values and find correct lines for total and free mem
    foreach ( $stats as $statLine ) $statLineData = explode ( «:» , trim ( $statLine ));

    //
    // Extract size (TODO: It seems that (at least) the two values for total and free memory have the unit «kB» always. Is this correct?
    //

    // Total memory
    if ( count ( $statLineData ) == 2 && trim ( $statLineData [ 0 ]) == «MemTotal» ) $memoryTotal = trim ( $statLineData [ 1 ]);
    $memoryTotal = explode ( » » , $memoryTotal );
    $memoryTotal = $memoryTotal [ 0 ];
    $memoryTotal *= 1024 ; // convert from kibibytes to bytes
    >

    // Free memory
    if ( count ( $statLineData ) == 2 && trim ( $statLineData [ 0 ]) == «MemFree» ) $memoryFree = trim ( $statLineData [ 1 ]);
    $memoryFree = explode ( » » , $memoryFree );
    $memoryFree = $memoryFree [ 0 ];
    $memoryFree *= 1024 ; // convert from kibibytes to bytes
    >
    >
    >
    >
    >

    if ( is_null ( $memoryTotal ) || is_null ( $memoryFree )) return null ;
    > else if ( $getPercentage ) return ( 100 — ( $memoryFree * 100 / $memoryTotal ));
    > else return array(
    «total» => $memoryTotal ,
    «free» => $memoryFree ,
    );
    >
    >
    >

    function getNiceFileSize ( $bytes , $binaryPrefix = true ) if ( $binaryPrefix ) $unit =array( ‘B’ , ‘KiB’ , ‘MiB’ , ‘GiB’ , ‘TiB’ , ‘PiB’ );
    if ( $bytes == 0 ) return ‘0 ‘ . $unit [ 0 ];
    return @ round ( $bytes / pow ( 1024 ,( $i = floor ( log ( $bytes , 1024 )))), 2 ) . ‘ ‘ . (isset( $unit [ $i ]) ? $unit [ $i ] : ‘B’ );
    > else $unit =array( ‘B’ , ‘KB’ , ‘MB’ , ‘GB’ , ‘TB’ , ‘PB’ );
    if ( $bytes == 0 ) return ‘0 ‘ . $unit [ 0 ];
    return @ round ( $bytes / pow ( 1000 ,( $i = floor ( log ( $bytes , 1000 )))), 2 ) . ‘ ‘ . (isset( $unit [ $i ]) ? $unit [ $i ] : ‘B’ );
    >
    >

    // Memory usage: 4.55 GiB / 23.91 GiB (19.013557664178%)
    $memUsage = getServerMemoryUsage ( false );
    echo sprintf ( «Memory usage: %s / %s (%s%%)» ,
    getNiceFileSize ( $memUsage [ «total» ] — $memUsage [ «free» ]),
    getNiceFileSize ( $memUsage [ «total» ]),
    getServerMemoryUsage ( true )
    );

    ?>

    The function getNiceFileSize() is not required. Just used to shorten size in bytes.

    Источник

    Читайте также:  Document
Оцените статью