Monday, July 27, 2009

ZendStudio 6.x.x performance issue

I have occasionally been plagued by less than stellar performance while using ZendStudio 6.x.x series. It happened again the other day and I finally made some progress in tracking it down, so let me share.

What happened

Recently I had to work on a fairly large PHP project on my laptop for a while. My normal environment is a 8 core MacPro, the laptop is a Core2Due MacBookPro. In both cases I run VMWare Fusion hosting a Fedora Core 10 guest as my development system. While I always thought things were somewhat slow on the desktop system, but manageable. Not so on the laptop. So I decided to look into it as I was wasting a lot of time. In particular one observed behavior was the right after starting up ZS cpu usages would go to 100% and stay there for quite a while, even though I was not "touching" anything. In fact it could last as long as 35 minutes.

Investigation first led me down the wrong path. My laptop is limited to 2.5GB memory and the VM I was using only had about 1.2GB. There was, however, no paging going on. I finally discovered that a serious amount of disk IO was happening. Then I discovered that a giant file existed in the php plugin's cache directory (/workspaces/DefaultWorkspace/.metadata/.plugins/org.eclipse.php.core/.cache). It was 74M. There was an accompanying file named "includes.xml" which made me suspicious. I peeked inside the giant file and found references to, and the content of, many files that had nothing to do with the project.

The cause

I wondered why ZS was even looking at these files, and then "the light went on." I use a "lib" directory that contains 3rd party libraries that I use, such as the Zend framework. Here is what that directory looked like:
[dolf@fc10 lib]$ ls -l
total 4
lrwxrwxrwx 1 dolf dolf 29 2009-07-27 15:01 jpgraph -> ../libreleases/jpgraph-2.3.3/
lrwxrwxrwx 1 dolf dolf 31 2009-07-27 15:00 krumo -> ../libreleases/krumo-0.2.1a-ds/
lrwxrwxrwx 1 dolf dolf 29 2009-07-27 14:59 Smarty -> ../libreleases/smarty-2.6.19/
drwxrwxr-x 8 dolf dolf 4096 2009-05-06 10:11 wso2
lrwxrwxrwx 1 dolf dolf 56 2009-07-27 14:58 Zend -> ../libreleases/ZendFramework-1.8.3-minimal/library/Zend/
Well, not quite! This is what it looked like after I solved the problem. Before the directories linked to where not in the "libreleases" directory, but in the "lib" directory. I figured that was fine because I included the "lib" directory on the include path and files would be referred to as "Zend/...".

Sure enough the files would be found, but somehow or other, ZS insists on inspecting every single file that is reachable via the include path. Since I had some 4-5 old versions of Zend Framework hanging around there, as well as some older version of the other stuff, the total amount of files inspected was many times more than necessary. After I "solved" this problem the aforementioned include file went from 74M to about 10MB. The 100% CPU period became much, much shorter.

The overall impact of this was even larger than you might think because a laptop's disk throughput is lower and because I had much less memory than on the desktop (8GB physical, 2GB for the VM), there was less use of a disk cache.

Startup settings

During my search I also encountered some ideas about optimizing the startup settings of Eclipse to make sure it had enough heap memory. I did apply those settings and they seemed to improve things as well. Here is the contents of my current ZendStudio.ini file:
--launcher.XXMaxPermSize 300M
-startup
plugins/org.zend.php.startup_1.0.0.jar
-vmargs
-Dorg.eclipse.swt.browser.XULRunnerPath=/home/dolf/Zend/ZendStudioForEclipse-6.1.1/plugins/org.mozilla.xulrunner.gtk.linux.x86_1.8.1.3-20070404/xulrunner
-Xms375M
-Xmx600M
The ones that are of particular interest here are:
  • XXMaxPermSize: The maximum size of the "permanent" generation on the heap. You may need to "play" with this for your situation.
  • Xms: This is the minimum size of the "regular" heap. Initially set it high and observe Ecelipse's "Heap Status" widget "Preferences>General>Show Heap Status". Wait until you have a stable situation typical of your normal workload. You should set the minimum size to something close to what you see here.
  • Xmx: This is the maximum size of the "regular" heap. Set it somewhat higher than the minimum as determined above.
There are potentially many other Java VM settings you can play with, but I'll leave that to you (I didn't touch them).

No comments: