This article describes performance-tuning techniques (PTT) for developing high performance and scalable JSP (JavaServer Pages) pages and servlets. That means building applications that are reasonably and consistently fast, and can scale up to the increasing number of users and/or requests. In this article, I walk you through the practical and proven performance-tuning techniques that will boost the performance of your servlets and JSP pages tremendously, thus improving the performance of your J2EE applications. Some of these techniques apply during the development phase, i.e., while you design your application and write the code. And some of these techniques are configuration-related.
PTT 1: Use the HttpServlet init() method for caching data
The server calls the servlet’s init() method after the server constructs the servlet instance and before the servlet handles any requests. It is called only once in a servlet’s lifetime. init() can be used to improve performance by caching the static data and/or completing the expensive operations that need to be performed only during initialization. For example, it is a best practice to use JDBC (Java Database Connectivity) connection pooling, which involves the use of the javax.sql.DataSource interface. DataSource is obtained from the JNDI (Java Naming and Directory Interface) tree. Performing the JNDI lookup for DataSource for every SQL call is expensive and severely affects an application’s performance. Servlet’s init() method should be used to acquire DataSource and cache it for later reuse:
PTT 2: Disable servlet and JSP auto-reloading
Servlet/JSP auto-reloading proves useful during the development phase because it reduces development time, as you do not have to restart the server after every change in the servlet/JSP. However, it is expensive in the production phase; servlet/JSP auto-reloading gives poor performance because of unnecessary loading and burdening on the classloader. Also, it may put your application in strange conflicts when classes loaded by a certain classloader cannot cooperate with classes loaded by the current classloader. So turn off auto-reloading for servlet/JSP in a production environment to receive better performance.
PTT 3: Control HttpSession
Many applications require a series of client requests so they can associate with one another. Web-based applications are responsible for maintaining such state, called a session, because the HTTP protocol is stateless. To support applications that must maintain state, Java servlet technology provides an API for managing sessions and allows several mechanisms for implementing sessions. Sessions are represented by an HttpSession object, but a cost is involved while using it. An HttpSession must be read by the servlet whenever it is used and rewritten when it is updated. You can improve performance by applying the following techniques:
Do not create HttpSessions in JSP pages by default: By default, JSP pages create HttpSessions. If you do not use HttpSession in your JSP pages, to save some performance overhead, use the following page directive to prevent HttpSessions from being created automatically when they are unnecessary in JSP pages: Do not store large object graphs inside an HttpSession: If you store the data in the HttpSession as one large object graph, the application server will have to process the entire HttpSession object each time. This forces Java serialization and adds computational overhead. The throughput decreases as the size of the objects stored in the HttpSession increases because of the serialization cost. Release HttpSessions when done: Invalidate sessions when they are no longer needed using the HttpSession.invalidate() method. Set session time-out value: A servlet engine has a default session time-out value set. If you do not either remove the session or use it for the time equal to the session time-out, the servlet engine will remove the session from memory. The larger the session time-out value, the more it affects scalability and performance because of overhead on memory and garbage collection. Try to keep the session time-out value as low as possible.
PTT 4: Use gzip compression
Compression is the act of removing redundant information, representing what you want in as little possible space. Using gzip (GNU zip) to compress the document can dramatically reduce download times for HTML files. The smaller your information’s size, the faster it can all be sent. Therefore, if you compress the content your Web application generates, it will get to a user faster and appear to display on the user’s screen faster. Not every browser supports gzip compression, but you can easily check whether a browser supports it and then send gzip-compressed content to only those browsers that do.
PTT 5: Do not use SingleThreadModel
SingleThreadModel ensures that servlets handle only one request at a time. If a servlet implements this interface, the servlet engine will create separate servlet instances for each new request, which will cause a great amount of system overhead. If you need to solve thread safety issues, use other means instead of implementing this interface. SingleThreadModel interface is deprecated in Servlet 2.4.
PTT 6: Use thread pool
A servlet engine creates a separate thread for every request, assigns that thread to the service() method, and removes that thread after service() executes. By default, the servlet engine may create a new thread for every request. This default behavior reduces performance because creating and removing threads is expensive. Performance can be improved by using the thread pool. Depending on the expected number of concurrent users, configure a thread pool by setting the values for minimum and maximum number of both threads in a pool and increments. At startup, the servlet engine creates a thread pool with number of threads in a pool equal to the minimum number of threads configured. Then the servlet engine assigns a thread from the pool to every request instead of creating a new thread every time, and returns that thread to the pool after completion. Using the thread pool, performance can drastically improve. If needed, more threads can be created based on the values for maximum number of threads and increments.
PTT 7: Choose the right include mechanism
There are two ways you can include files in a JSP page: include directive () and include action (). The include directive includes the specified file’s content during the translation phase; i.e., when the page converts to a servlet. The include action includes the file’s content during the request processing phase; i.e., when a user requests the page. Include directive is faster than include action. So unless the included file changes often, use include directive for better performance.
PTT 8: Choose the right scope in useBean action
One of the most powerful ways to use JSP pages is in cooperation with a JavaBeans component. JavaBeans can be directly embedded in a JSP page using the action tag. The syntax is as follows: Miscellaneous techniquesAvoid string concatenation: Avoid the use of System.out.println: ServletOutputStream versus PrintWriter: Using PrintWriter involves small overhead because it is meant for character output stream and encodes data to bytes. So PrintWriter should be used to ensure all character-set conversions are done correctly. On the other hand, use ServletOutputStream when you know that your servlet returns only binary data, thus you can eliminate the character-set conversion overhead as the servlet container does not encode the binary data.