I have yet to find an elegant solution for this. I have a class with a method I want to track the memory usage of without modifying the function:
class Example
{
public function hello($name)
{
$something = str_repeat($name, pow(1024, 2));
}
}
$class = new Example;
$class->hello('a');
So the task is, how much memory does hello()
use without interferring with it?
Note: The memory usage of this method should be 1MB. I've tried wrapping the call with memory_get_usage();
to no avail:
class Example
{
public function hello($name)
{
$something = str_repeat($name, pow(1024, 2));
}
}
$class = new Example;
$s = memory_get_usage();
$class->hello('a');
echo memory_get_usage() - $s;
This only results in 144
bytes (Not correct at all). I've tried various magic with Reflection by using the ReflectionMethod
class.
I have a feeling what I need to do is calculate the difference in the method :(. If someone can think of anything cleaner then you'd really make my day.
Edit: I should mention this is in the context of a benchmarking application. So while memory_get_peak_usage
works in the sense that it correctly returns the memory usage, it will also skew benchmarks ran after a high memory method. Now if there was a way to reset the memory stats, that could be good also.
Check Computer Memory Usage EasilyTo open up Resource Monitor, press Windows Key + R and type resmon into the search box. Resource Monitor will tell you exactly how much RAM is being used, what is using it, and allow you to sort the list of apps using it by several different categories.
You can use it by putting the @profile decorator around any function or method and running python -m memory_profiler myscript. You'll see line-by-line memory usage once your script exits.
You could use register_tick_function
and just dump memeory_get_usage
out every tick (line) and analysis it later. The class below could be improved by using debug_backtrace
to find line number related to memory usage or adding time per line using microtime
.
Profiler class
class Profiler
{
private $_data_array = array();
function __construct()
{
register_tick_function( array( $this, "tick" ) );
declare(ticks = 1);
}
function __destruct()
{
unregister_tick_function( array( $this, "tick" ) );
}
function tick()
{
$this->_data_array[] = array(
"memory" => memory_get_usage(),
"time" => microtime( TRUE ),
//if you need a backtrace you can uncomment this next line
//"backtrace" => debug_backtrace( FALSE ),
);
}
function getDataArray()
{
return $this->_data_array;
}
}
Example
class Example
{
public function hello($name)
{
$something = str_repeat($name, pow(1024, 2));
}
}
$profiler = new Profiler(); //starts logging when created
$class = new Example;
$class->hello('a');
$data_array = $profiler->getDataArray();
unset( $profiler ); //stops logging when __destruct is called
print_r( $data_array );
Output
Array (
[0] => Array (
[memory] => 638088
[time] => 1290788749.72
)
[1] => Array (
[memory] => 638896
[time] => 1290788749.72
)
[2] => Array (
[memory] => 639536
[time] => 1290788749.72
)
[3] => Array (
[memory] => 640480
[time] => 1290788749.72
)
[4] => Array (
[memory] => 1689800 // <~ money!
[time] => 1290788749.72
)
[5] => Array (
[memory] => 641664
[time] => 1290788749.72
)
)
Possible Issue
Since this profiler class stores the data in PHP, the overall memory usage will increase artificially. One way to sidestep this issue would be to write the data out to a file as you go (serialized), and when your done you can read it back.
The XHProfLive profiler developed by the Facebook guys gives this degree of function/method-level profiling, and available as a PECL download.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With