Archive

Archive for the ‘J2EE’ Category

Most Important Java 8 VM Options for Servers

java

Let’s talk about java enterprise server applications. I always want to know what are the best or default JVM settings for a server application to start with in production? I read a lot on the web and tried several things myself and wanted to share what I found out:

 

-server

Use “-server”: All 64-bit JVMs use the server VM as default. This setting generally optimizes the JVM for long running server applications instead of startup time. The JVM will collect more data about the Java byte code during program execution and generate the most efficient machine code via JIT.

-Xms=<heap size>[g|m|k] -Xmx=<heap size>[g|m|k]

The “-Xmx/-Xms” settings specify the maximum and minimum values for the JVM heap memory. For servers, both params should have the same value to avoid heap resizing during runtime.

Depending on your application, you will have to try out how much memory will be best suited for your application.

-XX:MaxMetaspaceSize=<metaspace size>[g|m|k]

Java 8 has no “Permanent Generation” (PermGen) anymore but requires additional “Metaspace” memory instead. This memory is used, in addition to the heap memory we specified before, for storing class meta data information.

The default size will be unlimited – I tend to limit MaxMetaspaceSize with a somewhat high value. Just in case something goes wrong with the application, the JVM will not hog all the memory of the server.

Note: Let your application run for a couple of days to get a feeling for how much Metaspace Size it uses normally. Upon next restart of the application set the limit to e.g. double the value.

-XX:+CMSClassUnloadingEnabled

Additionally, you might want to allow the JVM to unload classes which are held in memory but no code is pointing to them any more. If your application generates lots of dynamic classes, this is what you want.

-XX:+UseConcMarkSweepGC

This option makes the JVM use the ConcurrentMarkSweepGC – It can do much work in parallel to program execution but in some circumstances a “full GC” with a “STW pause” might still occur. I’ve read many articles and came to the conclusion that this GC is still the best one for server workloads.

-XX:+CMSParallelRemarkEnabled

The option CMSParallelRemarkEnabled means the remarking is done in parallel to program execution – which is what you want if your server has many cores (and most servers do).

 -XX:+UseCMSInitiatingOccupancyOnly
 -XX:CMSInitiatingOccupancyFraction=<percent>

Normally the GC will use heuristics to know when it’s time to clear memory. GC might kick in too late with default settings (causing full-Gcs).
Some sources say it might be a good idea to disable heuristics altogether and just use generation occupancy to start a CMS collection cycle. Setting values around 70% worked fine for all of my applications and use cases.

-XX:+ScavengeBeforeFullGC

The first option tells the GC to first free memory by clearing out the “young generation” or fairly new objects before doing a full GC.

-XX:+CMSScavengeBeforeRemark

CMSScavengeBeforeRemark does attempt a minor collection before the CMS remark phase – thus keeping the remark pause afterwards short.

-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses

The option “-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses” is especially important if your application uses RMI (remote method invocation). The usage of RMI will cause the JVM to do a FULL-GC EVERY HOUR! This might be a very bad idea for large heap sizes because the FULL-GC pause might take up to several seconds. It would be better to do a concurrent GC and try to unload unused classes to free up more memory – which is exactly what the second option does.

-XX:+PrintGCDateStamps
-verbose:gc
-XX:+PrintGCDetails
-Xloggc:"<path to log>"

These options shown here will write out all GC related information to a specified log file. You can see how well your GC configuration works by looking into it.

I personally prefer to use the “Visual GC” plug in for the “Visual VM” tool to monitor the general JVM and GC behavior.

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=<path to dump>'date'.hprof

When your JVM runs out of memory, you will want to know why. Since the OOM error might be hard to reproduce and you want to get your production server up and running again – you should specify a path for a heap dump. When things have settled down, you can analyze the dump afterwards.

-Djava.rmi.server.hostname=<external IP>
-Dcom.sun.management.jmxremote.port=<port>

These options will help you to specify an IP and port for JMX – you will need those ports open to connect remotely to a JVM running on a server for tools like VisualVM. You can gain deep insights over CPU and memory usage, gc behaviour, class loading, thread count and usage of your application this way.

Lastly, I would like to recommend to you the VisualVM tool which is bundled with the Java 8 JDK. You can use it to gain more insights about your specific application behaviour on the JVM – like cpu and memory usage, thread utilisation and much more.

VisualVM can be extended with a plug in called “Visual GC”. It will briefly show you VERY detailed information about the usage of the young and old generation object spaces. You can easily spot problems with garbage collection simply by analyzing these graphs during application runtime.

Advertisements
Categories: J2EE, Java

Simple guide to Java Message Service (JMS) using ActiveMQ

September 25, 2012 7 comments

JMS let’s you send messages containing for example a String, array of bytes or a serializable Java object, from one program to another. It doesn’t however use a direct connection from program A to program B, instead the message is sent to a JMS provider and put there in a Queue where it waits until the other program receives it.

MessageProducer is a Java program sending a JMS message to a Queue on the JMS Provider. MessageConsumer is another program which receives that message. These two programs can run on separate machines and all they have to know to communicate is the URL of the JMS Provider. The Provider can be for example a Java EE server, like JBoss or Glassfish. But don’t be afraid, you don’t need a full-blown JEE server to send a JMS message. In this article we will use ActiveMQ which is lightweight and easy to use.

First we need to download ActiveMQ. If you are using Linux, you can get it from this link. For Windows you can use this link. In case the links don’t work, you can find the files in ‘Downloads’ section on ActiveMQ’s webpage.

After the download, extract it to any directory and run the ‘activemq’ program from beneath the ‘{path-where-you-extracted-activemq}/bin’ directory:

You should see a bunch of INFO messages appearing on the terminal:

Now the ActiveMQ server is up and running. You can close it any time by pressing Ctrl-C. ActiveMQ has a nice admin console, where you can see a lot of useful informations and change the settings:

http://localhost:8161/admin/.

Now that we have a JMS provider running, let’s write our message producer and consumer programs. For that, you will need to put the ActiveMQ’s JAR file on the class path. The file you need is called (for version 5.6.0) ‘activemq-all-5.6.0.jar’ or something similar and is in the extracted ActiveMQ directory. In Eclipse you could click right mouse button on your project and choose Properties->Java Build Path->Libraries->Add External Library.

Here is the code of the program sending (producing) the messages:

package com.vallysoft.activemq.test;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Producer {
// URL of the JMS server. DEFAULT_BROKER_URL will just mean
// that JMS server is on localhost
private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
// default broker URL is : tcp://localhost:61616"

private static String subject = "VALLYSOFTQ"; //Queue Name
// You can create any/many queue names as per your requirement.

public static void main(String[] args) throws JMSException {
// Getting JMS connection from the server and starting it
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
Connection connection = connectionFactory.createConnection();
connection.start();
// JMS messages are sent and received using a Session. We will
// create here a non-transactional session object. If you want
// to use transactions you should set the first parameter to 'true'
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
// Destination represents here our queue 'VALLYSOFTQ' on the
// JMS server. You don't have to do anything special on the
// server to create it, it will be created automatically.
Destination destination = session.createQueue(subject);
// MessageProducer is used for sending messages (as opposed
// to MessageConsumer which is used for receiving them)
MessageProducer producer = session.createProducer(destination);
// We will send a small text message saying 'Hello' in Japanese
TextMessage message = session.createTextMessage("Hello welcome come to vallysoft ActiveMQ!");
// Here we are sending the message!
producer.send(message);
System.out.println("Sent message '" + message.getText() + "'");

connection.close();
}
}

There is a lot going on here. The Connection represents our connection with the JMS Provider – ActiveMQ. Be sure not to confuse it with SQL’s Connection. ‘Destination’ represents the Queue on the JMS Provider that we will be sending messages to. In our case, we will send it to Queue called ‘VALLYSOFTQ’ (it will be automatically created if it didn’t exist yet).

What you should note is that there is no mention of who will finally read the message. Actually, the Producer does not know where or who the consumer is! We are just sending messages into queue ‘VALLYSOFTQ’ and what happens from there to the sent messages is not of Producer’s interest any more.

Now let’s see how to receive (consume) the sent message. Here is the code for the Consumer class:

package com.vallysoft.activemq.test;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
* @author RudraG
*
*/
public class Consumer {
// URL of the JMS server
private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
// default broker URL is : tcp://localhost:61616"

// Name of the queue we will receive messages from
private static String subject = "VALLYSOFTQ";

public static void main(String[] args) throws JMSException {
// Getting JMS connection from the server
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
Connection connection = connectionFactory.createConnection();
connection.start();

// Creating session for seding messages
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);

// Getting the queue 'VALLYSOFTQ'
Destination destination = session.createQueue(subject);

// MessageConsumer is used for receiving (consuming) messages
MessageConsumer consumer = session.createConsumer(destination);

// Here we receive the message.
// By default this call is blocking, which means it will wait
// for a message to arrive on the queue.
Message message = consumer.receive();

// There are many types of Message and TextMessage
// is just one of them. Producer sent us a TextMessage
// so we must cast to it to get access to its .getText()
// method.
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
System.out.println("Received message '" + textMessage.getText()
+ "'");
}
connection.close();
}
}

As you see, it looks pretty similar to the Producer’s code before. Actually only the part starting from line 35 is substantially different. We produce there a MessageConsumer instead of MessageReceiver and then use it’s .receive() method instead of .send(). You can see also an ugly cast from Message to TextMessage but there is nothing we could do about it, because .receive() method just returns interface Message (TextMessage interface extends Message) and there are no separate methods for receiving just TextMessage’s.

Compile now both programs remembering about adding ActiveMQ’s JAR file to the classpath. Before running them be also sure that the ActiveMQ’s instance is running (for example in a separate terminal). First run the Producer program:

Successfully connected to tcp://localhost:61616
Sent message : Hello welcome come to vallysoft ActiveMQ!

If you see something similar to the output above (especially the ‘Sent message’ part) then it means that the message was successfully sent and is now inside the VALLYSOFTQ queue. You can enter the Queues section in the ActiveMQ’s admin console :

http://localhost:8161/admin/queues.jsp

and see that there is one message sitting in VALLYSOFTQ:

In order to receive that message run now the Consumer program:

Successfully connected to tcp://localhost:61616
Received message : Hello welcome come to vallysoft ActiveMQ!

If you are getting above input (or something similar) everything went ok. The message was successfully received.

You are now probably thinking “Why would anybody want to do that??”. In fact, the code presented here to transfer just a small text message was pretty big, and you also needed an instance of ActiveMQ running, and dependencies in the classpath and all that…. Instead of using JMS we could use plain TCP/IP with few times less effort. So, what are good points of using JMS compared to simple TCP/IP or Java RMI? Here they are:

  • Communication using JMS is asynchronous. The producer just sends a message and goes on with his business. If you called a method using RMI you would have to wait until it returns, and there can be cases you just don’t want to lose all that time.
  • Take a look at how we run the example above. At the moment we run the Producer to send a message, there was yet no instance of Consumer running. The message was delivered at the moment the Consumer asked ActiveMQ for it. Now compare it to RMI. If we tried to send any request through RMI to a service that is not running yet, we would get a RemoteException. Using JMS let’s you send requests to services that may be currently unavailable. The message will be delivered as soon as the service starts.
  • JMS is a way of abstracting the process of sending messages. As you see in the examples above, we are using some custom Queue with name ‘TESTQUEUE’. The producer just knows it has to send to that queue and the consumer takes it from there. Thanks to that we can decouple the producer from the consumer. When a message gets into the queue, we can do a full bunch of stuff with it, like sending it to other queues, copying it, saving in a database, routing based on its contents and much more. here you can see some of the possibilities.

JMS is widely used as a System Integration solution in big, distributed systems like those of for example banks. There are many books dealing with this huge topic, for example Enterprise Integration Patterns. If you want to learn more about JMS itself you can do it for example on this JMS Tutorial on Sun’s webpage.

Embedded Java – A Fresh Look at Embedded with Greg Bollella, Chief Architect.

Great news for Java lovers!!!
Java Technology is going to use in the embedded space.
“Now, embedded developers can download, install, and begin creating Java programs on typical embedded hardware in minutes.”Greg Bollella
(Chief Architect, Embedded Java, Oracle)
The Java language and runtime platform are pervasive in the embedded space. Today, Java technology is already present in 5 billion SIMs and Smart Cards, 3 billion mobile handsets, 80 million TV devices, including every Blu-ray player shipped, and many other embedded solutions from printers and bank machines to e-book readers and cars.
Java SE for Embedded
Java SE is commonly known as the platform that runs on desktops and servers. It offers a high-performance virtual machine, full high-performance graphics support, deployment infrastructure, and a rich set of features and libraries. Java SE for Embedded has been optimized for mid-range to high-end embedded systems.
  • Devices having 32MB (without graphics) or more for Java can use Oracle’s Java SE for Embedded
Java ME for Embedded
Oracle Java Micro Edition Embedded Client is based on Connected Device Configuration (CDC), a subset of the Java SE platform and draws from the origins of the Java platform, which was originally designed for embedded devices.  While scaled down to fit the limitations of resource-constrained devices and optimized for low to mid-range embedded-systems, Oracle Java ME Embedded Client provides most of the Java language and runtime features developers know and are accustomed to with Java SE.
  • Devices having 8MB (without graphics) or more for Java can use Oracle’s Java ME for Embedded

Welcome To Java Technical Blog

Welcome to Java Technical Blog.

This blog is completely for people those who came from java j2ee background :). All about Java Technology, Java related Technology and frameworks.

I will cover the following topic’s as follows:

  1. Java & J2EE Technology Discussion.
  2. Java with RFID Technology.
  3. Java with Near Field Communication(NFC).
  4. Java J2EE frameworks like Spring, Hibernate, Struts, JSF, JBoss Seam, JBoss Richfaces and many more.

Thank you visiting to my Java Technical blog.

With Best Regards,

RUDRA NARAYAN GARNAIK

www.garnaik.com : My Entertainment Blog.

http://java.garnaik.com – My Java FAQ blog.

%d bloggers like this: