Tracing PHP Memory Usage using Xdebug and Mamp on Mac

I recently wanted to see which parts of my app were using the most memory in a PHP script. I’ve been using Xdebug and webgrind on MAMP on my local machine and loving it. Derick Rethans wrote a post a few years ago about how to use Xdebug to profile memory usage and it was fairly easy to get it working.

1. Setup Xdebug on your Mac on MAMP.

2. Set Xdebug to output the needed function traces by adding the following to the php5.3.6.ini file:

xdebug.show_mem_delta = 1
xdebug.trace_format = 1
xdebug.trace_enable_trigger = 1
xdebug.auto_trace = 1
xdebug.trace_output_dir = "/tmp"

How to edit php .ini file in MAMP:

In context screenshot:

3. Restart MAMP

4. Download Derick’s parsing script to parse out memory usage from .xt trace files. I downloaded the script to my home directory to keep it simple.

5. Run PHP script that you want to measure memory usage from and confirm that .xt trace file is output to the /tmp directory. My output file was named

/tmp/trace.2043925204.xt

6. Run Derick’s memory parsing script against output .xt file

~/memory.php /tmp/trace.2043925204.xt memory-own 20

Example output:

parsing...
 
Done.
 
Showing the 20 most costly calls sorted by 'memory-own'.
 
                                 Inclusive        Own
function                 #calls  time     memory  time     memory
-----------------------------------------------------------------
{main}                        1  0.0345  2303008  0.0085  1894608
EpiRoute->addRoute          107  0.0058    97344  0.0034    92208
EpiApi->addRoute             61  0.0014    49304  0.0014    49304
EpiRoute->get                64  0.0050    65280  0.0017     6608
include_once                  8  0.0003     6376  0.0002     6120
Epi::getSetting             108  0.0024     5184  0.0024     5184
dbConnection                  2  0.0007     4760  0.0001     4568
EpiApi->get                  33  0.0062    63112  0.0014     4224
EpiRoute->post               43  0.0037    42736  0.0012     4064
EpiApi->post                 28  0.0058    54088  0.0013     3584
getApi                       61  0.0011     3344  0.0011     3344
mysqli->prepare               2  0.0003     2640  0.0003     2640
require                       4  0.0003     2312  0.0002     2312
session_start                 1  0.0001     2216  0.0001     2216
include                       5  0.0006     3192  0.0003      880
fsockopen                     2  0.0015      880  0.0015      880
func_get_args                 2  0.0000      840  0.0000      840
EpiTemplate->display          1  0.0008     4288  0.0002      776
EpiRoute::getInstance       108  0.0022      528  0.0022      528
EpiRoute->getRoute            1  0.0002      728  0.0001      480

Kynetx’s New Sandboxed Browser Extensions

I recently released my “Old School Retweet” Kynetx app in the Kynetx app store for the newly released browser extensions. I super love the new extensions and all that they do for users and developers alike. Something that I forgot when I released the app in the app store is that the new extension are sandboxed.

Because the extensions are sandboxed, all of the scripts from the extensions run a bit differently than they used to in the previous Kynetx extensions. Without getting into the technical details too much, the previous extensions just injected JavaScript into the page and the new extensions run JavaScript in a sandbox which has access to the DOM but can’t access anything else on the page. Because of this change my retweet app broke since I was using the jQuery loaded by Twitter.com to bring up the new tweet box (I do this because Twitter.com used that library to bind a click event and to trigger that event it has to be from the same library that bound it). Thankfully, with the help of a friend, I was able to get a work around for both Firefox and Chrome’s sandbox environment.

How I did it…

If the app is run not inside a sandbox I can just access the jQuery that Twitter.com loads to open a new tweet box

$("#new-tweet").trigger("click");

From within the Firefox sandbox I can access the page outside of the sandbox

window['$']("#new-tweet").trigger("click");

If I am in the Chrome sandbox I can create a script element that has the JavaScript that I want to execute. Crude, but it works. : )

var trigger_click_script = document.createElement("script");
var fallback = "window['$']('#new-tweet').trigger('click');";
trigger_click_script.innerHTML = fallback;
document.getElementsByTagName("head")[0].appendChild(trigger_click_script);

Here is the JavaScript code that I ended up with that gets executed when a user clicks on the retweet button.

// get stuff to retweet
var tweet = $K(this).parents(".tweet-content").find(".tweet-text").text();
var name = $K(this).parents(".tweet-content").find(".tweet-screen-name").text();
 
// build tweet
var retweet = "RT @"+name+" "+tweet;
 
// open new tweet box
$("#new-tweet").trigger("click");
 
// hack for FF sandbox
if ($("#tweet-dialog:visible").length === 0) {
  window['$']("#new-tweet").trigger("click");
}
 
// put tweet in new tweet box
$K(".draggable textarea.twitter-anywhere-tweet-box-editor").val(retweet).focus();
$K("#tweet_dialog a.tweet-button.button.disabled").removeClass("disabled");
 
// hack for chrome sandbox
if ($("#tweet-dialog:visible").length === 0) {
  var fallback = "window['$']('#new-tweet').trigger('click'); ";
  fallback += "window['$']('.draggable textarea.twitter-anywhere-tweet-box-editor').val('"+retweet+"').focus(); ";
  fallback += "window['$']('#tweet_dialog a.tweet-button.button.disabled').removeClass('disabled'); ";
  var trigger_click_script = document.createElement("script");
  trigger_click_script.innerHTML = fallback;
  document.getElementsByTagName("head")[0].appendChild(trigger_click_script);
}

How To Rename Mac Terminal Tabs

I’ve been running a lot of terminal windows lately and getting lost in all the tabs has been annoying. I started searching for a solution and figured out that it’s super easy to rename the tabs in the terminal for Mac OS X! While on a terminal tab just use the keyboard shortcut of cmd + i to pull up the inspector window and then rename it. Easy!

Unnamed terminal tabs:

Menu option to bring up inspector:

After using cmd + i to bring up Mac Terminal Inspector:

After renaming tabs in Terminal:

If when you bring the inspector window up with cmd + i and the focus isn’t in the “Title” input, you can use shift + cmd + i to put the focus there. You can then press enter to apply the title change or just press escape to apply the title change and close the inspector.

If you liked this or have other cool ideas, let me know in the comments or on Twitter @MikeGrace

CSS Navigation Border Experiment

I was working on building navigation based on this mockup

Navigation Mockup

Navigation Mockup

I enjoyed building the navigation and thought what I came up with was cool enough to share what I did.

The JavaScript added is just to simulate changing pages.

Example page -> http://mikegrace.s3.amazonaws.com/geek-blog/sandbox/css-nav-border-party.html