Out-of-memory error
LessCSS Filter
Last weekend I released the code for the LessCSS Filter (transforms LESS files into CSS files on the server instead of the user's browser) that I use on this site and that I talked about in this blog post. I created a public repository on GitHub, placed the source code into that repository for others to check out, and added a download link on the repository page for those who just want to use the filter without delving into the source code.
The GitHub repository can be found here: ultraq/lesscss-filter
YUI Compressor Filter
I did a similar thing for the YUI Compressor Filter (something also used on this site, performs server-side minification/compression of stylesheet (including LESS) and JavaScript resources).
That GitHub repository can be found here: ultraq/yuicompressor-filter
Out of memory
To split these 2 small pieces of functionality into their own self-contained packages, I took advantage of some features available in the latest version of Java Servlets, something called 'web fragments'. Then when I was folding the separated parts back into my website, I used 'Servlet 3.0 annotations' to swap configuration files for in-code annotations (which I'm a big fan of). Together these made things a lot more convenient for me and it left the whole website feeling a bit 'lighter', simply because there was less stuff in the code base for me to worry about.
So last weekend I stopped my server, uploaded all the new bits and pieces of this website that I had been working on, started the server up again, and... nothing happened. I did some digging and found that plenty actually did happen: hundreds of lines of logging about how the server was running out of memory!
How the hell can my website be consuming so much memory? I wondered. The VPS on which my website resides only has 512MB of memory, which isn't a lot by any modern-day PC standards, but is plenty when all the server has to do is host a small website like this. So I started breaking it all down, trying to find out how that 512MB got divvied up:
- 1/10th for the OS and other OS services I enabled (a necessity)
- 1/10th for the website database (reasonable)
- 6/10ths for the application server before the updates (whoa... wait a minute)
- over 8/10ths for the application server after the updates (...dammit)
I investigated further and found that the Servlet 3.0 annotations feature was the real memory killer - using it causes the startup memory usage to spike beyond the remaining memory before settling-down somewhere within it. Without any room for that spike to happen, the application server couldn't start up, and so I got out-of-memory errors.
For any Java web developers amongst you, the application server I was using was Tomcat - a very popular and lightweight application server that I've been using for the last 7 or so years. Apparently, 'lightweight' only applies when you don't use Servlet 3.0 annotations, so to keep my site running for the last week, that's exactly what I did: removed annotations and went back to using a configuration file to keep my memory budget in the black.
Doing this felt like I was taking a step back in time - having to use older programming methods to stick to my memory constraints - and I didn't like it. I already step back in time enough in my day job (which drives me insane when I have to think about or work with how held-back some of those systems are) that I didn't want to have to do it here as well. This website is supposed to be my way of keeping up with the latest and greatest stuff (or at least 2 steps ahead of whatever my work is using) that I had to find another way.
So I went to scope out the alternatives.
The only alternative to Tomcat that I hear or read about is an application server called Jetty. It's written to the same specifications that Tomcat is, and when I read some of the goals of Jetty on their project pages, my optimism started to kick-in: words like 'efficient', 'embeddable', and 'smallest footprint' were used throughout the place that I started thinking, This is exactly what I'm after!
I downloaded the Jetty application server, threw my website at it, and there were only 2 problems in the migration: both related to code that I wrote which contradicted itself; both of which Tomcat never picked up on. Jetty also started up much faster than Tomcat, somewhere between 3 and 4 times faster! As for the memory footprint: there was no memory spike when using annotations, and the memory usage after startup was about 100MB less than Tomcat!
Suffice it to say, I deployed Jetty to my VPS as soon as I was able :D