How does your blog look with zoomed fonts?
Try your own site. Readability is in--small fonts are so 1997.
Labels: blog
Try your own site. Readability is in--small fonts are so 1997.
Labels: blog
I couldn't pick a better launchpad. Go, Edwards (and Scoble).
Paul tagged me, so here goes:
Enough about me. I hereby tag Sam, Keith, Cedric, Mike, and my mom.
Dave, web browser capabilities pragmatically drove JSON's Javascript-like format. Unlike XML-based protocols, you can use a JSON service across different web sites with existing browsers (without a server side proxy, Flash, etc.).
I suppose you could base the protocol on XML if you really wanted to, but you'd still have to provide a Javascript wrapper. Fewer browsers support natively parsing XML than Javascript, and performance would suffer. We do all have Ghz machines nowadays, but today's browsers seem to need that and more; I can't believe Firefox still manages to hang for seconds at a time on my Mac Pro.
Sites often offer JSON APIs in addition to XML APIs to support pure browser-based usages. del.icio.us has had an XML API for a long time; they use RSS! If I were calling an API from Java, I'd use the XML not the JSON API.
That said, I'm personally not a fan of the current JSON spec. If you structure your Javascript like the following example, you can support complex graphs, circular references, etc., whereas the current spec. only supports hierarchies: a={};b={};c='foo';a.foo='c';a.bee=b;b.ay=a;
Me: Gulp.
Jacob is exploring caching information related to Java Class instances.
Say for example we need collections of getter methods in classes. Rather than filter out the getter methods every time we need them, we can build the collection of getters once and cache the result in a static map:
/** Maps a class to getter methods in that class. */ static Map<Class<?>, Collection<Method>> getterCache = ...;
Problems arise when the garbage collector needs to reclaim a Class instance to which our map holds a strong reference. This could happen if our cache class is in the system class path and a class in our cache is from a web application.
When we go to reload the web application, our cache class keeps a strong reference to the web application class which keeps a strong reference to its class loader which keeps strong references to all of the other web application classes--memory leak.
If you can, store the cache somewhere where it will free up at the same time as the classes it caches. For example, in the case of a web application, we might store the cache in the servlet context.
If you must keep strong references from a static scope, you have to keep a WeakReference to the Class instance making it available for garbage collection. Jacob pointed out that we need to keep a WeakReference to the cache key, but often times your value also has a strong reference to the Class instance.
In our getter example, our value is a list of methods. Those methods each keep a strong reference to their class--memory leak. How do we fix this? We can't keep a weak reference to the value itself in this case. In between usages of our cached data, we'll hold the only reference. We could wrap each Method instance in a weak reference, but I find keeping a SoftReference to the cached value works just fine. Plus, the garbage collector can reclaim values which we don't access often.
How do we implement this cache? It just so happens I've created a class ReferenceCache which solves this exact problem. ReferenceCache wraps ConcurrentHashMap and references keys and values however you like, strongly, softly or weakly.
Compared to using a WeakHashMap, ReferenceCache abstracts more of the caching logic so you don't have to write code to check for a value, create a value, and put the value in the cache over and over. You only write code to create the value.
Where WeakHashMap uses equality to compare keys, ReferenceCache compares weakly and softly referenced objects by identity; weak and soft references are inherently identity based.
WeakHashMap cleans up after garbage collected keys in the same code path as your map operations. Thanks to the ConcurrentHashMap behind the scenes, ReferenceCache can perform these cleanups in a background thread.
What's more, ReferenceCache creates values canonically, i.e. it will only create one value per key at a time. This comes in handy pretty much any time you need a canonical map and prevents extraneous value creations other times.
Getting back to our getter example, a ReferenceCache-based implementation goes something like this:
static Map<Class<?>, Collection<Method>> getterCache = new ReferenceCache<Class<?>, Collection<Method>>( WEAK, SOFT) { protected Collection<Method> create(Class<?> clazz) { Collection<Method> getters = new ArrayList<Method>(); for (Method m : clazz.getMethods()) if (isGetter(m)) getters.add(m); return getters; } }; static boolean isGetter(Method m) { String name = m.getName(); return name.length() > 3 && name.startsWith("get") && Character.isUpperCase(name.charAt(3)) && m.getParameterTypes().length == 0 && !Modifier.isStatic(m.getModifiers()) && ...; }
Now, what do we do about Super Type Tokens? ;)
P.S. Any time you cache objects, run performance tests to determine whether your cache really does more good than harm.
I can separate the Java items into their own feed if you like. Let me know.
Ted recently ran into this problem, too. He was lucky enough to get off with a warning, but my code actually needs to differentiate between List<Integer> and List<String>.
Neal came to the rescue with a clever (and cleverly named) pattern for retaining otherwise non-reifiable types at runtime. Check out super type tokens.
In a nutshell, instead of saying List<Integer>.class, you can say new TypeReference<List<Integer>>() {}, where the API for TypeReference may look very similar to that of Class.