Erlang progress update: I've been sidetracked by working on some Java reflection for $DAYJOB (not bad/unfreindly stuff, just needed to work through it), so I'm now back on my side project. Working through Joe Armstrong's book, I'm now looking at Erlang records (pg 69+). Records seem like a cool to add names to tuples so you end up with something that feels like a name-value pair map or, if you take the analogu further, almost like an object. Granted the tuple is just a linked list, and I'm not sure of the implementation of a record, if it keeps an index of pointers to each named tuple 'field', or anything like that (yeah, I coulda google'd - its still early though), but still, a handy feature for OO folks.
Monday, March 2, 2009
Thursday, February 26, 2009
Java Annotations and Proxies
Just discovered this: If you create a class with annotations of any kind, those annotations (and any other metadata) is lost when the object is proxied. Google searching didn't turn too much on the subject, but I did find this post about one work around (but it only relates to Hibernate). This seems sort-of innocuous on the surface (from a language/API level), but with every framework under the sun using reflection/proxies to add real value, this really does suck.
Any suggestions would be greatly appreciated. So would free cocktails....
UPDATE: OK- here's what I've now uncovered. In my original case, I was getting a bean via Spring and was trying to get the annotations by simply reflecting on various methods - no dice. In my real world case, however, I am looking at the target object via an aspect (meaning, I am inspecting the invoked object while in the aspect code). From the ProceedingJoinPoint object that is a parameter into my aspect method, I can see all the annotations.
I think I still need a cocktail...
Any suggestions would be greatly appreciated. So would free cocktails....
UPDATE: OK- here's what I've now uncovered. In my original case, I was getting a bean via Spring and was trying to get the annotations by simply reflecting on various methods - no dice. In my real world case, however, I am looking at the target object via an aspect (meaning, I am inspecting the invoked object while in the aspect code). From the ProceedingJoinPoint object that is a parameter into my aspect method, I can see all the annotations.
I think I still need a cocktail...
Tuesday, February 17, 2009
Erlang "processes" clarified
Now that I'm into erlang, I've been going through the Getting Started guide on the erlang.org site, and I found this little nugget:
the term "process" is usually used when the threads of execution share no data with each other and the term "thread" when they share data in some way. Threads of execution in Erlang share no data, that's why we call them processes.I was always confused about erlang "processes" - if they were full-blown executable VM and OS-level processes or what have you. It's getting clearer now...
Thursday, February 12, 2009
New Project - Erlang E-commerce
Well, now that we've moved to California (Sept 2008), and things are finally settling in, I'm looking for a new project to play with. At the end of long conversation with a current coworker, Steve Atkinson, about concurrency and the bear that it can be to wrestle with (especially in regards to shared state) I admitted that I'm interested in seeing how the new crop of functional programming languages deal with these types of issues.
So, to jump on a bandwagon (that's probably already left the station), I've decided to started exploring Erlang. What I want to do is create a small e-commerce style of application to see how the non-shared state model deals with the state of objects/entities like "customer", "order", and "product" over the lifetime of the application. I suspect my point of departure will look like a typical Java web-app (it's how I pay the rent), but am hoping to divert into something more or a true erlang app (whatever that may be). Further, since I have absolutely no background in functional languages, this should be a good learning and growing experience.
I'll try to jounal as much of the interesting details, thoughts, and ideas as I go along. However, we're expecting our second baby in about six weeks (holy cow!), so I'm not sure how much progress I'll make in the spring or summer. Either way, I'm hoping to gain another perspective on this whole programming thing...
So, to jump on a bandwagon (that's probably already left the station), I've decided to started exploring Erlang. What I want to do is create a small e-commerce style of application to see how the non-shared state model deals with the state of objects/entities like "customer", "order", and "product" over the lifetime of the application. I suspect my point of departure will look like a typical Java web-app (it's how I pay the rent), but am hoping to divert into something more or a true erlang app (whatever that may be). Further, since I have absolutely no background in functional languages, this should be a good learning and growing experience.
I'll try to jounal as much of the interesting details, thoughts, and ideas as I go along. However, we're expecting our second baby in about six weeks (holy cow!), so I'm not sure how much progress I'll make in the spring or summer. Either way, I'm hoping to gain another perspective on this whole programming thing...
Tuesday, December 9, 2008
Creating a Java annotation
So I created a new (method-level) annotation that basically just takes a string, and when the target method is invoked, via aspect I get that string. The annotation looks like this (name changed to protect the innocent):
public @interface Annotatable { String value(); }
After a few hours of banging my head, trying to figure out why everything compiled correctly, yet when testing I could never get the find the annotation on the target method. Turns out, this was soooo poorly documented by Sun/Java gods, you need to annotate your annotation, like this:
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
The RetentionPolicy enum tells the compiler to keep the annotation around AFTER you compile, instead of throwing it away (like it does by default). The Target annotation tells the compiler which types of elements your annotation can apply to (classes, methods, params, all, etc.). The long and short of it is: don't forget to annotate your annotations.
public @interface Annotatable { String value(); }
After a few hours of banging my head, trying to figure out why everything compiled correctly, yet when testing I could never get the find the annotation on the target method. Turns out, this was soooo poorly documented by Sun/Java gods, you need to annotate your annotation, like this:
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
The RetentionPolicy enum tells the compiler to keep the annotation around AFTER you compile, instead of throwing it away (like it does by default). The Target annotation tells the compiler which types of elements your annotation can apply to (classes, methods, params, all, etc.). The long and short of it is: don't forget to annotate your annotations.
Wednesday, August 6, 2008
NUMA and the JVM
Good blog entry from Jon Masamitsu about NUMA optimizations in Java 6 on Solaris. NUMA, essentially, and vastly simplified, is to access a region of memory that is physically closer to a processer on a multi-processor system. This way there's less latency when reading/writing to the general memory region. For Java, the optimizations are made primarily to the Eden (young generation) heap space, as well as assigning a thread to a particular CPU.
To enable the feature. it's a command-line param to the JVM at startup: -XX:+UseNUMA .
To enable the feature. it's a command-line param to the JVM at startup: -XX:+UseNUMA .
Java 6 threading article
An article on Java 6 threading optimizations recently appeared on infoq. It's a good article in two parts, but here I'm just going to capture some of the interesting notes about the different locking features now in the JVM (most of this entry is paraphrase - that is, notes to myself).
Escape analysis - determine the scope of all references in an app. If HotSpot can determine the refs are limited to local scope and none can esacpe, it can have the JIT apply runtime optimizations.
Lock elision - when refs to a lock are limited to local scope (for example creating an modifying a StringBuffer), no other thread will ever have access to object; hence it is never contended for. Then, you really don't need the lock anyway and can be elided/omitted.
Biased Locking - most locks are never accessed by more than one thread, and even when multiple threads do share data, access is rarely contended. Long story short, this makes subsequent lock acquisitions less expensive by holding onto lock until somebody else wants it. Java 6 does this by default now.
Lock Coarsening (or merging) - occurs when adjacent synchronized blocks may be merged into one (if same lock is used for all methods). For example. when calling a series StringBuffer append() operations. Locks are not coarsened inside of a loop because the lock will be held for (potentially) too long.
Thread suspending versus spinning - When a thread waits for a lock, it is usually suspended by the OS. This involved taking it off the stack, rescheduling, etc. However, most locks are held for very brief time periods (based on profiling), so if the second just waits a little bit without being suspended, it can probably acquire the lock it wants. To wait it just goes into a busy loop - known as spin locking. Was introduced in Java 1.4.2 with a default (fixed) spin of 10 iterations before suspending the thread.
Adaptive Spinning - Spin duration not fixed anymore, but policy based on previous spin attempts on same lock and state of lock owner. If spinning likely to succeed, will go for a longer iterations count (say, 100); else, will bail on spinning altogether and suspend.
Introduced in Java 6.
Escape analysis - determine the scope of all references in an app. If HotSpot can determine the refs are limited to local scope and none can esacpe, it can have the JIT apply runtime optimizations.
Lock elision - when refs to a lock are limited to local scope (for example creating an modifying a StringBuffer), no other thread will ever have access to object; hence it is never contended for. Then, you really don't need the lock anyway and can be elided/omitted.
Biased Locking - most locks are never accessed by more than one thread, and even when multiple threads do share data, access is rarely contended. Long story short, this makes subsequent lock acquisitions less expensive by holding onto lock until somebody else wants it. Java 6 does this by default now.
Lock Coarsening (or merging) - occurs when adjacent synchronized blocks may be merged into one (if same lock is used for all methods). For example. when calling a series StringBuffer append() operations. Locks are not coarsened inside of a loop because the lock will be held for (potentially) too long.
Thread suspending versus spinning - When a thread waits for a lock, it is usually suspended by the OS. This involved taking it off the stack, rescheduling, etc. However, most locks are held for very brief time periods (based on profiling), so if the second just waits a little bit without being suspended, it can probably acquire the lock it wants. To wait it just goes into a busy loop - known as spin locking. Was introduced in Java 1.4.2 with a default (fixed) spin of 10 iterations before suspending the thread.
Adaptive Spinning - Spin duration not fixed anymore, but policy based on previous spin attempts on same lock and state of lock owner. If spinning likely to succeed, will go for a longer iterations count (say, 100); else, will bail on spinning altogether and suspend.
Introduced in Java 6.
Wednesday, July 2, 2008
devWorks Benchmarking article
This is a great article from the IBM devWorks site about Java performance benchmarking. I'm just capturing some notes in this entry.
Measuring time:
Measuring time:
- System.currentTimeMillis() - gets the "wall clock" time, but the updates from the OS are hardware dependent and may only occur every ~10 ms. call to OS returns instantly
- System.nanoTime() - returns a differential time, measured in microseconds, bu the call to the OS itself can take microseconds.
- ThreadMXBean - JMX extension that offers to read a Thread's CPU usage (may be misleading due to I/O and it's uage may be expensive)
- Class loading can be observed via ClassLoadingMXBean
- Most VMs run the code for while in interpreted mode to gether stats before performing JIT compilation. Sun's Hot Spot defaults: 1500 time for client VMs, 10,000 for server. Could use CompilationMXBean to measure JIT time, but impl is hosed. Alternative is to watch stdout with -XX:+PrintCompilation JVM option
Subscribe to:
Posts (Atom)