Monday, November 9, 2009

Eliminating obsolete objects reference with profiling tools

I'm getting ready for my Miami Java User Group (MJUG) talk on December with buddy Antonio Llanos. We thought about doing a "performance and scalability" talk. I wanted to focused on the tools (specially open-source) that a programmer should have to help them analyze their applications. I also wanted for the attendants to come out of the talk knowing exactly what they should do the next day.

I also wanted to come up with snippet of code that would not be so easy to detect to show the importance of these tools. It was then when I stumbled with a piece of code from Effective Java 2nd Edition, "Item 6: Eliminate obsolete objects references". The code is a simple stack class (LIFO algorithm), which has a memory leak.

package com.midc.spikes.effectivejava.obsoleteobject;

//Can you spot the "memory leak"?

import java.util.*;

public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;

public Stack() {
elements
= new Object[DEFAULT_INITIAL_CAPACITY];
}

public void push(Object e) {
ensureCapacity();
elements[size
++] = e;
}


public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}

/**
*
* Ensure space for at least one more element, roughly
* doubling the capacity each time the array needs to grow.
*/

private void ensureCapacity() {
if (elements.length == size)
elements
= Arrays.copyOf(elements, 2 * size + 1);
}

public int getSize() {
return size;
}
}


I couldn't find the memory leak. According to the book,
If a stack grows and then shrinks, the objects that were popped off the stack will not be garbage collected, even if the program using the stack has no more references to them.

To fix the problem, we just need to null the reference of the object that is popped.

public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result
= elements[--size];
elements[size]
= null;
return result;
}

The book also explains, that these bugs are hard to detect, and that most the best way to find them is through "careful code inspection or with the aid of a debugging tool known as a heap profiler". As always, it is very desirable to find these type of problems ahead of time to prevent them from happening. In other words, exactly what I needed for my talk.

Tuesday, November 3, 2009

Application Performance Management

I have been working on a topic for the Miami Java User Group. Lately, I have been doing a great deal of performance and scalability for my projects. Thanks to my friend Edson Cimionatto, he let me borrow the Apress' Pro Java EE 5 by Steven Haines. It is a nice book and I have been reading part of the chapters, so today I reviewed some of my notes. Looking back there are four things that really cought my attention:
  1. Have SLAs
  2. Performance applies the rule of "better to do it from the start" or "earlier is cheaper"
  3. Have a set of tools to diagnose the application (memory, code profiling, and code coverage)
  4. There is a "culture" aspect on tackling performance. Not only you need to do tests, and have a decent architecture, but you have to be willing to be relentless on keep the performance metrics (SLAs)

Wednesday, October 28, 2009

Technical debt

InfoQ has a great article about technical debt. Most of all, I like one of the definition of Uncle Bob,
A mess is not a technical debt. A mess is just a mess. Technical debt decisions are made based on real project constraints. They are risky, but they can be beneficial. The decision to make a mess is never rational, is always based on laziness and unprofessionalism, and has no chance of paying of in the future. A mess is always a loss.
I have always known that some technical debts are unavoidable, but had a hard time deciding who should be the person that dictates what should be technical debt. The answer, the team. The team should be the one that decides (as long as we can provide all the parameters and waive all the risks and benefits) what should be included in the technical debt. I agreed with Martin Fowler,
The key lies in making sure that a team is not introducing reckless debts which contribute to the mess and are very difficult, if not impossible to deal with.

Thursday, September 24, 2009

Metaphors, valuable assets in conversations.

The company is in negotiations on selling one of my source code to one of our competitors. I was asked by the CEO to talk to the CFO regarding the risks and to come up with a price. The conversation was going nowhere. The CFO was totally lost regarding the source code. It was obvious that he did not understand the context of the conversation. Finally, I told him to think as the source code as a recipe. "Think of us as Coca-Cola (the company) and we have the recipe, the "secret formula", and now some other competitor like Pepsi wants to purchase it."

After that, we were both engaged on the conversations. The CFO was asking questions such as:
  • if we give them the recipe, they (competitors) can make as many cokes as they please.
  • how long did it take your team to create the recipe (in terms of hours, and most of all money).
All these questions contributed to a really good conversation. Afterwards, the CFO and I talked to the CEO and discussed our assessment.

In the book, Pragmatic Thinking and Learning, Andy Hunt explains methaphors and software as the following:
The idea is that any software system should be able to be guided by an appropriate metaphor

I couldn't agree more with him.

Tuesday, September 22, 2009

Hudson CI

I love the whole concept of Continuous Integration (CI). My first interaction with CI was using Cruise Control along with a team of Thought Works (great guys!). However, I noticed that the configuration is all XML and it could be cumbersome. In my previous project, only a few individuals really know how to configure it.

I have been slacking on using CI (not proud of it) for two reasons:
1. I only have two programmers and they are here in Miami. Most of the time they pair programed together.
2. I didn't want to bring the pain of XML into the company.

However, I just acquired a new programmer and he is located in Mexico. I have also noticed broken builds due to items not being checked, some broken unit tests, etc. Perfect candidates for CI. Last week, I decided that instead of calling the programmers and asked them to solve the problem, I would install a CI server but not Cruise Control. I have heard a lot of great things from Hudson. Today I just finished the installation. Really nice and easy. Now, I need to finished the configuration with the deployment, SVN, and other few items. But, I'm really exited to be back into the CI world. My team should be more effective and hopefully we can increase the amount of deployments. It was wrong for me of not using CI from the beginning. Even if we would have implemented Cruise Control we would be better than today.

Monday, September 21, 2009

mysqldump from external db to local db

Sometimes I need to transfer data from my remote database (product/test) to my local box. I usually use dbUnit to avoid the transfer. However, sometimes I need to use specific data to solve either a specific bug. If you are using MySQL, then most likely you are using mysqldump. It's a really good tool. Here is how I transfer data from my test environment (marcelo.prod) to my local box without affecting (delte, truncate, or doing anything to my current schema):

mysqldump -h marcelo.prod -uprod_username -pprod_password --skip-create-options --no-create-info --no-create-db --compact --skip-add-drop-database --insert-ignore --where="OPERATOR_SERVICE = 'MBLOX_US'"  upmobile OPERATOR_TBL | mysql -uroot -psecret upmobile

I also use this code to transfer data from my production database to my historic database.