The Guava Cache library works one level above ConcurrentHashmap but doesn’t offer as much features as Ehcache. Guava caches aren’t pre-loaded by default and are all thread safe. The loading of a cache is done with an implementation of the abstract class CacheLoader.
The build of the cache is done progressively, starting by a call to the static method CacheBuilder.newBuilder(), then chaining calls to methods from class CacheBuilder. This allows to specify its configuration and especially its eviction strategy for values : value accessed least recently with expireAfterAccess(long, TimeUnit), value modified least recently modified with expireAfterWrite(long, TimeUnit) … Besides time goes, eviction of values can be activated by specifying the maximum total weight of the cache with a call to maximumWeight(long), requiring also a call to weigher(Weighter) to indicate how to weigh a cache entry.
The build of the cache terminates by calling build() or build(CacheLoader), which returns a new Cache instance.
Besides classical features, cache statistics can be activated by calling the recordStats() method. Usage of the removalListener(RemovalListener) method allows to know when a value has just been deleted from the cache. By default, this notification is synchronous, which can slow down cache operations. To process notifications asynchronously, you must wrap your RemovalListener by calling RemovalListeners.asynchronous(RemovalListener, Executor). While building the cache, a call to refreshAfterWrite(long, TimeUnit) will schedule an automatic refresh of a value some time after its creation or its last modification. In some cases, it’s more interesting to load all cache values once by overloading the CacheLoader.loadAll(Iterable) method.
Among features, there is Cache.get(K, Callable) to get a value from the cache by specifying how to add it when it’s missing. In this case, a unique call to Callable is done by the cache, even if multiple threads are asking the value for that key. Finally, it’s possible to get a view of the cache as a ConcurrentMap by calling asMap().
To take benefit of the hot deploy of new CRaSH commands, you must develop commands with groovy by extending the CRaSHCommand class. It’s also possible to write commands in Java by implementing the ShellCommand interface, but without getting benefit of the hot deploy. A CRaSH command can also be developed as a groovy script. Besides addition of new commands, a plugin mechanism allows to add new features by extending the CRaSHPlugin class.
Among available standard commands, the jdbc command allows to connect to a database through a DataSource defined in a JNDI directory or directly by using a JDBC connection string. It’s then possible to directly execute SQL queries. Among other available commands, there is the thread command to control threads and the log command to manage logs.
By default, you can connect to a CRaSH instance by SSH or by Telnet but it can be disabled. For more informations, have a look at the documentation.
Thanks to CRaSH, you can for example write scripts to test a Swing application by using the java.awt.Robot class.
Among libraries manipulating bytecode, there are EJB containers, terracota to distribute computations and hibernate. The eclipse plugin managing layout and display of Android screens also manipulates bytecode to instrument the real library used in Android.
Then, Julien and Frédéric present quickly the java bytecode : each primitive type is internally represented by a letter, class packages are represented with a slash instead of dots (example : java/lang/String)… The virtual machine whose goal is to run the bytecode is a pushdown automaton with an area containing constants (constant pool) and another containing code to execute (opcode). To illustrate that, they demonstrate execution of bytecode generated by compilation of a simple System.out.println to display the result of an addition. We can then see the stack and variables (processor registries) evolving.
ASM is one of the libraries allowing to manipulate bytecode. It has 2 APIs :
An API based on an event model, structured around the visitor design pattern. It can be used to profile java code, by implementing the ClassFileTransformer interface.
An API based on an object model, loading all the bytecode in memory as a syntax tree of the code (AST).
AspectJ is another library manipulating bytecode. This one allows to do aspect-oriented programming (AOP) to, for example, add logs (method calls…), security (verify access to some services) or validation (verify form fields) …
To illustrate that, Julien and Frédéric are doing 2 demonstrations around the computation of Fibonacci number, in a recursive way : the first one is very slow and does some computations multiple times, the second one is a lot faster because it uses AspectJ to implement a cache of already done computations.
Another possible use case is the modification of a class to add it the implementation of an interface not implemented before.
Byteman, another library manipulating bytecode, implements an agent modifying classes in a running JVM, to debug for example. It also provides a bytecode injector, to use in the setup of a JUnit test. It’s then possible, for example, to force File.mkdirs() to return false, allowing to improve test coverage.
To achieve its task, Byteman defines a language close to the bytecode, allowing to specify modifications to apply and the place to put them.
To end the presentation, Julien and Frédéric present us the beta version of a research project named JooFlux (it will be soon open sourced). This project uses Rémi Forax‘s work on the new bytecode named invokedynamic (introduced in Java 7). Byteman modifies completely a class, even if only one of its methods has changed (that forces the JIT compiler to optimize again all the methods). In contrast, JooFlux only modifies what is necessary, which will optimize the usage of JIT compiler. JooFlux also provides a Swing/JMX interface to manage bytecode injection. As an example of usage, you can replace all calls to invoke* by a call to invokedynamic.
For more informations on bytecode, you can have a look at slides of the presentation titled JVM Bytecode for Dummies made by Charles Nutter at JavaOne 2011.
To begin, Romain is speaking about threads in Android (subject that I am starting to know well) by saying us to not block the main thread, also known as UI thread because user interface operations must run inside it. To avoid blocking it, you must use the Handler class and its post(Runnable) method or use the AsyncTask class (equivalent to the SwingWorker class for Swing). About the AsyncTask class, Romain indicates it’s possible to call the executeOnExecutor method to use a custom thread pool. Since Android 3, 2 standard Executors exist : AsyncTask.SERIAL_EXECUTOR and AsyncTask.THREAD_POOL_EXECUTOR.
Then he advises us to activate the strict mode to verify an application has good behaviours (see the StrictMode documentation). It verifies in particular you are executing operations (inputs/outputs, graphical interface modification …) in the good thread (see my other article on the subject).
On the side of memory and processor usage, the creation of a View is very expensive, as well as inflation of the xml describing it. A TextView costs 800 bytes of memory.
About layouts, you must use them the least possible and avoid as much as possible the LinearLayout, especially if it’s associated with the android:layout_weight attribute.
He advises us to apply the following rules :
Avoid stacking layouts (it can give a stackoverflow if there is too much levels) as much as possible.
Think about overloading views in order they do only what you need, unlike standard views.
Avoid calling the View.requestLayout() method. However, it’s automatically called when text size of a TextView has changed.
Remove new as much as possible, especially in onDrawXxx methods from View class
He continues by presenting the ViewStub component, to use when a view is displayed from time to time. Its main properties are id corresponding to the stub identifier and inflatedid representing the associated view identifier. When the ViewStub.inflate method is called, the stub is removed from the hierarchy of views and replaced by the associated view.
About tools, he presents traceview to measure performances, hierarchyviewer to see views loaded in memory (especially the allocation tracker tab visible in the eclipse plugin) and lint to analyze layouts and source code.
To analyze memory used by an application, there is the adb shell dumpsys meminfo command. The first column, titled Pss is the most interesting one. The line titled other dev corresponds to memory used by the graphical chipset, especially for textures. For more informations on resource used by the graphical chipset, you can type adb shell dumpsys gfxinfo.
Then, Romain speaks about hardware acceleration for graphical rendering. First of all there is the android:hardwareAccelerated attribute, available since version 14 of Android API, which can be positioned at many levels : application, activity, window, view. It’s possible to combine different levels for finer tuning. Here is some other optimization technics he gives us :
LAYER_TYPE_SOFTWARE : software rendering in a bitmap, expensive because it uses the main memory and the graphic chipset’s memory but it can solve some problems with hardware rendering.
LAYER_TYPE_HARDWARE : rendering by the graphic chipset. So, it’s faster and only one memory allocation is done.
Layers must be used carefully because they are expensive in term of memory and processor time.
About animations, it’s possible to animate properties (used for graphical rendering) inside an interval of values. To make it works, a getter and a setter are necessary for each property to animate. When it’s possible, standard properties (like View.x) must be used. These are more optimized because their animation doesn’t use the reflection API. At the end of the animation, you must not forget to remove the layer by calling setLayerType(LAYER_TYPE_NONE).
During the session of questions, I asked him how to improve performances of vertical scrolling in lists (ListView) with a lot of elements.
He replied performances doesn’t depend on number of elements and advised me to use the traceview tool to analyse performances. He also underlined that until Android 2.3 (included), there is no synchronisation with VSync, which can impact performances while scrolling a list.
Thanks Romain for all these informations about Android ! I have learned a lot of things
Seren, meaning SERialization ENhancer, is a free software allowing to speed up serialization of Java objects. It can, for example, be used for a faster persistance of objects in Ehcache or to speed up remote method calls with RMI.
To do its job, Seren is based on an agent manipulating the Java bytecode of a class to add writeObject and readObject methods as specified in the Serializable interface. If they already exist, Seren doesn’t modify the class.
Among implemented optimisations, classes wrapping primitive types (Integer, Long …) are replaced by their associated primitive type (int, long …), plus a boolean indicating if the value is null. About String, they are encoded in UTF-8 (instead of UTF-16), when it’s possible.
About performances, Seren is effectively faster for small objects but it’s not that good for big objects. It uses a bit more memory than classic serialization. About the compatibility, data serialized by Seren are obviously not binary compatibles with classic Java serialization. It also uses the sun.misc.Unsafe class, that isn’t part of the Java API, which means it’s not necessarily supported by a JVM other than Hotspot (the Sun Oracle JVM). It happens with IBM’s JVM.
To note : Olivier has used the thrift-protobuf-compare library to measure Seren performances. This library allows to compare performances of various serialization protocols based on the Java platform. Results (not including Seren), are available here. If you are searching for a serialization library (not only in a binary format, but an xml or a json format) for various languages based on Java platform (Scala …), I invite you to consult the list of tested libraries on the thrift-protobuf-compare site. Some of them also manages various languages not based on the JVM (C, C++, Python, Javascript …).
Using Seren is rather easy : put the Javassist library (allowing bytecode manipulation) in the classpath and add the Seren agent. No modification into the source code is necessary. To indicate classes to modify, it’s possible to use one of the ClassFilter implementations from the net.thecodersbreakfast.seren.filter package.
By taking the dining philosophers problem as example, they show us that an inappropriate strategy can lead to a DeadLock. In the case of a database, the engine chooses the deadlock victim by returning an SQL exception to one of the involved clients. On the other hand, in the case of a Java program with a minimum of 2 threads trying to access 2 resources (after they have locked them), there is no exception to indicate a thread is involved in a DeadLock (in that case, it would be good that the thread throw an Error).
The solution to this problem (named Left-Right DeadLock) is to apply the following strategy to all the philosophers :
take (lock) the flatware on his right side
take (lock) the flatware on his left side
put down (unlock) the flatware on his left side
put down (unlock) the flatware on his right side
Remarks :
It’s certainly possible to take the opposite strategy : the left side flatware, then the right side one. The essentiel is that all philosophers apply the same strategy.
It’s important that a philosopher put down its flatwares in the opposite order he has taken them
Instead of using right-left notion, it’s possible to number each flatware with a unique number. In this case, there are 2 possible strategies : start by taking the flatware with the smallest number (among the 2 ones located near the philosopher), start by taking the flatware with the biggest number. Again, it’s important that all philosophers apply the same strategy. It gives a generic solution to DeadLock problems : define a strict order among resources (by associating them for example to a unique numerical identifier) and apply the “smallest first” strategy.
Among concrete cases, there is the private writeObject(ObjectOutputStream) method from Vector class, synchronized on the instance. A DeadLock could occur while serializing 2 vectors containing a reference to the other.
For the unit test side, how to check a DeadLock is fixed ? How many time should the test be played to prove the fix is working ? Indeed, a DeadLock can happen from time to time and not always systematically. A good test must pass or not, independantly from external conditions (load of processor …). Heinz and Olivier propose to add an empty method named sleep into the production code and call it between 2 attempts to lock 2 different resources. By overloading the sleep method into the test code to call Thread.sleep(long), it becomes possible to reveal the presence or the absence of a DeadLock in a determinist way.
Since Java 6, there is new features allowing to make it easier to detect and fix a DeadLock :
Visualize threads state of a running JVM :
Under Windows : The JVM must have been launched in a console and type Ctrl-Break
Under Linux : If the JVM has been launched in a console, type Ctrl-\. Else, send the QUIT signal to the process with the command kill -QUIT process_id, where process_id is the process identifier (you can find it with the command ps axf | grep java)
List threads involved in a DeadLock by using JMX. It only works for locks of the same type used by ReentrantLock and not for locks using a monitor (keyword synchronized).
To illustrate that, Heinz and Olivier have created a class named DeadlockArbitrator that kills a random thread among the ones involved in a DeadLock (the list is obtained through JMX). Then, they show a demonstration of a Swing application with a button to create a DeadLock and another to kill a thread involved in a DeadLock (by using the DeadlockArbitrator class).
Remark : to kill a thread, the DeadlockArbitrator class uses the deprecated method (useful in our case) Thread.stop(Throwable). This technic must only be used for code that you can’t fix (third party libraries). In other cases, you must obviously fix the DeadLock.
For more informations on technical subjects like this one, Heinz invite us to look at his site Javaspecialists.eu
If, like me, you are developing under an Android version older than version 4 (also named Ice Cream Sandwich or ICS), you must have seen the SDK Manager doesn’t propose you to get the sources.
In fact, it’s possible to manually download them. For that purpose, you must go to the grepcode site, where one can find sources for all versions since 1.5. You must choose the version that interest you in the right side of the page, then download the sources as a jar file by clicking on the link “Source download”. Finally, under eclipse (or your favorite IDE), you can associate these sources with the android.jar library. It’s more practical to debug
Remarks :
For versions before ICS, all sources are not available
You can also consult sources online by exploring the tree located at the left side of grepcode site
While I was developing under android, I discovered 3 exceptions thrown by android to indicate execution of code in the wrong thread.
The first case is about execution of a request with the apache HTTP client, provided with android. The android documentation advice to use the AsyncTask class for long tasks, in order to avoid blocking the main thread (used to update the graphical interface). An HTTP request must always be considered as a long task because a fast request at a given time might take more time in production (because the network or the server can be more loaded sometime). Android 3 (API 11) force that good practice by throwing a NetworkOnMainThreadException exception if you use the main thread to execute an HTTP request.
The second case is about updating the graphical interface in the wrong thread. If you are in that case, then android will throw a CalledFromWrongThreadException exception (apparently not documented in the android javadoc) with the message Only the original thread that created a view hierarchy can touch its views.. That happened to me by calling indirectly the following code from the AsyncTask.doInBackground method :
loginEditText and passwordEditText are fields whose type is EditText
The code is running in a thread created by the AsyncTask class. If, instead of using AsyncTask, you create directly a new thread or use a component that do it, you will have the same problem.
The third case is a variant of the previous one. Here, there is no specific exception but a RuntimeException with the less explicit message Can’t create handler inside thread that has not called Looper.prepare() when the AlertDialog.Builder.create method is called.
When that arrived to me, I have replaced the following code :
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
...... (initialization of the dialog box)
alertDialog.show();
by this one :
Activity activity = ......; // get the activity
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog alertDialog = new AlertDialog.Builder(activity).
create();
...... (initialization of the dialog box)
alertDialog.show();
}
});
As I had to do an HTTP request under android, I started to write the following code using the apache HTTP client API (included in android) :
// create and initialize the apache http client
final HttpClient httpClient = ......;
// create and initialize the http request
HttpPost httppost = ......;
ResponseHandler rh = new ResponseHandler() {
public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
HttpEntity entity = response.getEntity();
if (entity != null) {
StringBuilder out = new StringBuilder();
byte[] b = EntityUtils.toByteArray(entity);
out.append(new String(b, 0, b.length));
return out.toString();
} else {
return "";
}
}
};
String responseString = httpClient.execute(httppost, rh);
After a problem, I discovered the server returned an http error 403 (access forbidden). So, I added the highlighted code below in order to manage the case it doesn’t return OK :
// create and initialize the apache http client
final HttpClient httpClient = ......;
// create and initialize the http request
HttpPost httppost = ......;
ResponseHandler rh = new ResponseHandler() {
public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
if (response.getStatusLine().getStatusCode()
== HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
if (entity != null) {
StringBuilder out = new StringBuilder();
byte[] b = EntityUtils.toByteArray(entity);
out.append(new String(b, 0, b.length));
return out.toString();
} else {
return "";
}
} else {
StatusLine sl = response.getStatusLine();
String message = "HTTP error " + sl.getStatusCode() +
" Reason: " + sl.getReasonPhrase();
throw new HttpErrorException(message);
}
}
};
String responseString = httpClient.execute(httppost, rh);
remark : I have created the HttpErrorException class that inherits from IOException to stay compliant with the handleResponse method specifications from the ResponseHandler interface.
After that modification, the caller must catch HttpErrorException to process specifically the case when the server doesn’t return OK.
With Java / Swing, each showXxxDialog method in the JOptionPane class creates a modal dialog box waiting for a user action. It’s modal because the user can’t do any action outside this one. Let’s take the following example :
int response = JOptionPane.showConfirmDialog(null,
"Do you want to delete this file ?",
"Confirmation",
JOptionPane.YES_OPTION);
if (response == JOptionPane.YES_NO_OPTION) {
// ... action if response = Yes
}
We can see the call is synchronous, which means the method returns a value that allow to process the response immediately.
Under Android, dialog boxes are also modals. But the processing of the response must be done asynchronously.
So, one must use a different programming strategy, based on callback. In the example of a Yes/No dialog box, a callback for the Yes answer is needed and eventually another one for the No answer. The code for Android looks like this :
Activity activity = .....; // find the current Activity
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage("Do you want to delete this file ?");
// definition of the callback for the Yes answer
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// ... action if answer = Yes
}
});
builder.show(); // doesn't return user's choice
// after this line, the user may not have already answered
// to the question (because the call is asynchronous)
In order to make the code a bit clearer, I create an abstract class called Command :
abstract public class Command implements DialogInterface.OnClickListener {
@Override
public final void onClick(DialogInterface dialog, int which) {
execute();
dialog.dismiss();
}
abstract public void execute();
}
I also write the following method :
public void displayYesNoDialog(Activity context, int messageId,
Command yesCommand) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(context.getString(messageId));
builder.setPositiveButton("Yes", yesCommand);
builder.show();
}
I use it like that :
Activity activity = .....; // find the current Activity
int messageId = .....; // find the message identifier
Command yesCommand = new Command() {
public void execute() {
// ... action if answer = Yes
}
displayYesNoDialog(activity, messageId, yesCommand);