Is your J2EE application running slowly? Can they withstand rising traffic? This article describes the performance optimization technology for developing high-performance, highly elastic JSP pages and Servlets. The idea is to build as fast as possible and adapt to the growing number of users and their requests. In this article, I will lead you to learn practical and proven performance tuning techniques that will greatly improve the performance of your servlets and jsp pages, thereby improving the performance of J2EE. Some of these technologies are used in development phases, such as design and coding phases. Another part of the technology is related to configuration.
Technique 1: Caching data in the HttpServletinit() method
The server calls the servlet's init() method after creating the servlet instance and before the servlet handles any requests. This method is called only once in the servlet's life cycle. To improve performance, cache static data in init() or perform expensive operations to be done during initialization. For example, one best practice is to use a JDBC connection pool that implements the javax.sql.DataSource interface.
DataSource is obtained from the JNDI tree. It is very expensive to use JNDI to find the DataSource every time SQL is called, and it seriously affects the performance of the application. The Servlet's init() method can be used to obtain the DataSource and cache it for later reuse:
publicclassControllerServletextendsHttpServlet
{
privatejavax.sql.DataSourcetestDS=null;
publicvoidinit(ServletConfigconfig)throwsServletException
{
super.init(config);
Contextctx=null;
try
{
ctx=newInitialContext();
testDS=(javax.sql.DataSource)ctx.lookup("jdbc/testDS");
}
catch(NamingException)
{
ne.printStackTrace();
}
catch(Exception)
{
e.printStackTrace();
}
}
publicjavax.sql.DataSourcegetTestDS()
{
returntestDS;
}
...
...
}
Technique 2: Disable the auto-loading function of servlets and JSPs
. You will have to restart the server every time you modify the Servlet/JSP. Since the autoloading feature reduces development time, this feature is considered very useful during the development phase. However, it is very expensive in the runtime phase; servlet/JSP causes poor performance due to unnecessary loading and increased burden on the class loader. Again, this can cause your application to have strange conflicts because classes that have been loaded by a certain class loader cannot cooperate with classes loaded by the current class loader. Therefore, in order to obtain better performance in the running environment, turn off the automatic loading function of servlet/JSP.
Technique 3: Control HttpSession
Many applications require a series of client requests so they can be related to each other. Since the HTTP protocol is stateless, web-based applications need to be responsible for maintaining such a state called session. In order to support applications that must maintain state, Javaservlet technology provides APIs that manage sessions and allow multiple mechanisms to implement sessions. The HttpSession object acts as a session, but there is a cost to using it. Whenever HttpSession is used and overridden, it is read by the servlet. You can improve performance by using the following techniques:
lDo not create a default HttpSession in the JSP page: By default, the JSP page creates an HttpSession. If you do not use HttpSession in your JSP page, in order to save performance overhead, use the following page instructions to avoid automatically creating HttpSession objects:
< %@pagesession="false"% >
1) Do not store large object graphs in HttpSession: If you store data in HttpSession as a large object graph, the application server will have to process the entire HttpSession object each time . This will force Java serialization and increase computational overhead. Due to the overhead of serialization, the throughput of the system will decrease as the data objects stored in the HttpSession object increase.
2) Release the HttpSession after use: When the HttpSession is no longer in use, use the HttpSession.invalidate() method to invalidate the session.
3) Set the timeout value: A servlet engine has a default timeout value. If you do not delete the session or keep using the session until it times out, the servlet engine will delete the session from memory. Due to the overhead in memory and garbage collection, the larger the session timeout value, the greater its impact on system resiliency and performance. Try to set the session timeout value as low as possible.
Technique 4: Use gzip compression
Compression is the practice of removing redundant information and describing your information in as small a space as possible. Using gzip (GNUzip) to compress documents can effectively reduce the time of downloading HTML files. The smaller your messages, the faster they are sent. Therefore, if you compress the content generated by your web application, the faster it reaches the user and is displayed on the user's screen. Not every browser supports gzip compression, but it's easy to check if a browser supports it and send gzip-compressed content to the browser. The code snippet below illustrates how to send compressed content.
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsIOException,ServletException
{
OutputStreamout=null
//ChecktheAccepting-EncodingheaderfromtheHTTPrequest.
//Iftheheaderincludesgzip,chooseGZIP.
//Iftheheaderincludescompress,chooseZIP.
//Otherwisechoosenocompression.
Stringencoding=request.getHeader("Accept-Encoding");
if(encoding!=null&&encoding.indexOf("gzip")!=-1)
{
response.setHeader("Content-Encoding","gzip");
out=newGZIPOutputStream(response.getOutputStream());
}
elseif(encoding!=null&&encoding.indexOf("compress")!=-1)
{
response.setHeader("Content-Encoding","compress");
out=newZIPOutputStream(response.getOutputStream());
}
else
{
out=response.getOutputStream();
}
...
...
}
Technique 5: Don't use SingleThreadModel
SingleThreadModel guarantees that the servlet only handles one request at a time. If a servlet implements this interface, the servlet engine will create a separate servlet instance for each new request, which will cause a lot of system overhead. If you need to solve thread safety issues, please use other methods instead of this interface. The use of SingleThreadModel is no longer recommended in Servlet2.4.
Technique 6: Use the thread pool
servlet engine to create a separate thread for each request, assign the thread to the service() method, and then delete the thread after the service() method is executed. By default, the servlet engine may create a new thread for each request. Since creating and deleting threads is expensive, this default behavior reduces system performance. We can use thread pool to improve performance. According to the expected number of concurrent users, configure a thread pool and set the minimum and maximum number of threads in the thread pool as well as the minimum and maximum growth values. Initially, the servlet engine creates a thread pool with a number of threads equal to the minimum number of threads in the configuration. The servlet engine then assigns a thread from the pool to a request instead of creating a new thread each time. After completing the operation, the servlet engine puts the thread back into the thread pool. Using thread pools, performance can be significantly improved. If needed, more threads can be created based on the maximum number of threads and the number of growth.
Technique 7: Choose the correct include mechanism
In JSP pages, there are two ways to include files: include instructions (< %@includefile="test.jsp"% >) and include actions (<jsp:includepage="test.jsp "flush="true"/>). The include directive includes the contents of a specified file during the compilation phase; for example, when a page is compiled into a servlet. An include action involves including file content during the request phase; for example, when a user requests a page. Including instructions is faster than including actions. Therefore, unless the included files change frequently, you will get better performance by using the include directive.
Technique 8: Use appropriate scopes in useBean actions
One of the most powerful ways to use JSP pages is to work with JavaBean components. JavaBeans can be embedded into JSP pages using the <jsp:useBean> tag. The syntax is as follows:
<jsp:useBeanid="name"scope="page|request|session|application"class=
"package.className"type="typeName">
</jsp:useBean>
The scope attribute describes the visible scope of the bean. The default value of the scope attribute is page. You should choose the correct range based on your application's needs, otherwise it will affect your application's performance.
For example, if you need an object specific to some request, but you set the scope to session, that object will remain in memory after the request ends. It will remain in memory unless you explicitly delete it from memory, invalidate the session, or the session times out. If you don't choose the correct scope attribute, performance will be affected due to memory and garbage collection overhead. So set a suitable scope for objects and delete them as soon as you are done with them.
Miscellaneous techniques
1) Avoid string concatenation: Since String objects are immutable objects, using the "+" operator will result in the creation of a large number of zero-time objects. The more "+" you use, the more zero-time objects will be generated, which will affect performance. When you need to concatenate strings, use StringBuffer instead of the "+" operation.
2) Avoid using System.out.println: System.out.println processes disk input/output synchronously, which greatly reduces system throughput. Avoid using System.out.println whenever possible. Although there are many mature debugging tools available, sometimes System.out.println is still useful for tracing or debugging purposes. You should configure System.out.println to only open it during error and debugging phases. Using a finalBoolean variable, when configured to false, optimization checks and execution trace output are completed during the compilation phase.
3) Comparison of ServletOutputStream and PrintWriter: Due to the character output stream and encoding of data into bytes, using PrintWriter introduces a small performance overhead. Therefore, PrintWriter should be used after all character set conversions have been done correctly. On the other hand, when you know that your servlet will only return binary data, use ServletOutputStream because the servlet container does not encode binary data, so you eliminate the character set conversion overhead.
Summary
The purpose of this article is to show you some practical and proven performance optimization techniques for improving servlet and JSP performance, which will improve the overall performance of your J2EE applications. The next step should be to observe performance tuning of other related technologies, such as EJB, JMS, and JDBC.