29 August 2009

Stale Beer

True story: Last Friday at noon I went on my usual bike ride in the hills that surround the office park that I work at. As me and my co-worker were descending a small hill, the driver of a (blue?) car traveling in the opposite direction threw a half-empty can in our direction and managed to hit me with a glancing blow square in the chest. I had less than a half second to react to this. Thankfully, I was completely fine from the whole incident. The car disappeared, and there was nothing I could do about the whole incident -- I had no description of the car, no license plate, and I wasn't carrying a cell phone either. The only thing that I could hope for from the incident was that the people driving behind the (blue?) car would have seen the incident and called the police.

After the coward(s) in the car disappeared, my co-worker asked what had happened. Since the can that hit me was blue, I assumed that the can was a can of Pepsi. So I told my co-worker that some idiot threw a can of Pepsi at me.

There was nothing we could do at this point except to continue the ride. So, that's what we did.

When I got back to the office, I sat down at my desk to cool off. There in my cube, in the absence of a 20mph breeze from riding my bike, I took a few breaths and tried to figure out what the strange smell was. Then it hit me: stale beer. That coward in the car threw a half empty can beer at me!

Oh, wonderful. Not only was this driver cowardly enough to throw something at a bicyclist, but he/she also had an open container of beer in the car too, in handy enough reach to throw at me.

I wish this driver had had enough courage to stop...I'm sure I could have convinced him/her that what they did was wrong.

19 August 2009

Big Ohh.

Did you know that if you replace an some code that (1) is frequently executed, (2) runs over a large data-set, and (3) implements an O(n^2) algorithm with some code that is implemented in terms of an O(n) algorithm that things will go quite a bit faster!? Yessirree, it is true!

18 August 2009

Too many of them

So, the other day I'm standing in the deli in my local grocery store. It is Sunday afternoon. The store is busy. I'm trying to pick up some pastrami that is on sale.

The clerks behind the deli counter serve customers according to the numbers on the little tickets that everybody picks up when they arrive at the deli. This is the same system that is used at 10,000 other delis.

I'm holding number "9". The 50-ish year-old woman standing next to me is holding the number "8". The clerks at the deli are now helping the customer with the number "7".

Eventually, customer #7 gets what they want. So, now it's time for the next number. One of the clerks says in a loud voice "who's next?". There is an awkward pause and then I hear one of the clerks ask in a loud voice "who is next -- what is the number after '7'?" Me and the 50-ish year-old woman look at each other quizzically. After a second she suggests to the clerk that eight is the number after seven, at which point in time the clerk says "Yeah, that's it! Eight is the next number. Who has number eight?". Me and customer #8 exchange a knowing look.

Eventually, customer #8 gets her Polish ham (sliced medium), and I get my pastrami (sliced thin). When I get home, my wife notices that I didn't actually get the pastrami that I asked for ("thin and trim") but instead got some other kind. Customer #8 seemed to be a much more savvy shopper than I was -- I'll bet she managed to get what she asked for.

I think that Beavis and Butthead summed up this situation nicely:

[a teacher asks Butt-head if he is angry for some reason]
Butt-head: Uhhhh... I'm, like, angry at numbers.
Beavis: Yeah, there's like, too many of them and stuff.


13 August 2009

Java Memory Usage

Dear Lazyweb,

Suppose I am writing a large server, and my implementation language is Java. The memory requirements for the server are larger than what the Sun JVM provides by default. So, I need the configure the JVM to use more memory.

This isn't rocket science. Everybody knows about Sun's "-Xmx" flag.

Here is Sun's documentation for the -Xmx flag:

-Xmxn
Specify the maximum size, in bytes, of the memory allocation pool. This value must a multiple of 1024 greater than 2MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is 64MB. The upper limit .... [elided since the limits are a lot higher nowadays....] Examples:

-Xmx83886080
-Xmx81920k
-Xmx80m

There are a couple of things that confuse me about this flag. First of all, take a look at what runs just fine on my server box:

$ java -Xmx1000g HelloWorld
Hello, world!

I can assure you that my server box does not have 1000GB of any sort of memory!

More confusingly, here is another test I can run:

$ java -Xmx1000g SomeLongRunningProgram &
$ java -Xmx1000g SomeLongRunningProgram &

So, now I've got two programs running on my server box that seem to expect that they will, at some point in the program's runtime, be able to allocate 1000GB each for the memory pool. In my mind, this means that not only do I not have enough memory here, but the memory that I do have on this machine is heavily oversubscribed.

This whole situation confuses the heck out of me. My background includes quite a bit of embedded systems programming, and in the embedded world systems typically allocate their memory up front and then treat this memory as if it was a precious resource. If you can't allocate the memory that you need up front, you know something is wrong right away and it needs to be fixed. You don't get this behavior with the Sun JVM "-Xmx" flag.

OK, so, given the work that I have at hand, the "-Xmx" flag does not give me the behavior that I wanted. So, I looked into this a little bit more and thought about this problem. Soon, I was focusing my attention on the "-Xms" flag. Here's the documentation for this:

-Xmsn Specifies the initial size of the memory allocation
pool. This value must be a multiple of 1024
greater than 1 MB. Append the letter k or K to
indicate kilobytes or the letter m or M to indicate
megabytes. The default value is 2MB. Examples:

-Xms6291456
-Xms6144k
-Xms6m

So, after thinking about this a little bit, I eventually arrived at the following pattern for specifying memory allocation for server applications:

java -Xms1024m -Xmx1024m MyServer

The point is, I am specifying the same values for "-Xms" and "-Xmx". This pattern ensures that the JVM tries to allocate the memory that it needs up front. It isn't hard for me to experiment with my server machine and to learn how much memory I can allocate. If I allocate too much, I know about the problem right away. My server's memory never gets "oversubscribed" either.

So, I think that this pattern of specifying the same values for both "-Xms" and "-Xmx" is a good pattern for Java-based server applications. In fact, after a few minutes of searching, I came across this page, which seems to offer the same advice:

Setting -Xms and -Xmx to the same value increases predictability by removing the most important sizing decision from the JVM.

So, my question is this: under what circumstances would it be advantageous to specify different values for "-Xms" and "-Xmx"? I don't see a lot of upside for doing this, especially since I know that writing solid code that handles out-of-memory errors is a pretty difficult thing to do.