directory

  • A request execution process
  • How does Java code work?
  • What happens when the heap is full?
  • How to optimize system performance with singleton pattern?

Hello, everyone. Today I’m going to share with you a design pattern for writing code, which is the most familiar singleton design pattern.

Many people may have heard of this singleton design pattern, and even write the thief slip, but today to tell you about using this singleton design pattern, we are how to greatly improve the performance of the code, singleton pattern and code performance relationship, I’m afraid many brothers have not seriously studied it!

A request execution process

First let’s look at what singletons are. To understand singletons, we need to talk about how we create objects without singletons.

Usually creating objects is easy, for example, we make an external Web interface, and then when the interface receives a request, we create an object.

The pseudocode looks like this:

@RestController("/user")
public class Controller {
  
  private UserService userService;
  
  @RequestMapping("/create")
  public Response create(CreateUserRequest request) {
    User user = new User(request);
    
    UserService userService = new UserService();
    userService.add(user);
    
    returnResponse.success(); }}Copy the code

The code above is extremely simple. Suppose you have a Controller that provides an HTTP interface, and then each time you send a request through the browser to create a user.

So for the /user/create URL, send a CreateUserRequest, and the code will create a user object using the new keyword, and then create a UserService component using the new keyword, It then passes the User object to the UserService component to insert the User data into the database. This code is basic but should be understood by anyone who knows Java.

But there’s a question here, do you know what this code does when it runs every time it handles a request?

In fact, the most important point is that he creates a User object and a UserService object in memory for each request. How do these objects are created?

How does Java code work?

First of all, when you start a Java program, you always start a JVM process. For example, you might start it using the main method in a framework like Spring Boot. It can also be packaged and put into Tomcat to run.

If you run the main method directly, you will start a JVM process directly. If you package your code and run it in Tomcat, tomcat is itself a JVM process, as shown in the following figure.

Then, you start the JVM process, will take you to write good code loaded into memory to then run the code, you wrote in your code to run, he can do what you want him, for example, receive browser sends an HTTP request, and then create some objects, inserted into the database, etc., as shown in the figure below.

Where is the object created when your code runs with new User() and new UserService()?

JVM process is very simple, you is a piece of his own memory area can be used, and he can use, this area is called the heap memory, this is similar to our own home build a cottage, to own a piece of yard can grow grass and flowers in it, others can’t grow cucumbers and garlic in your yard, right, the following figure.

So what happens next, this code that we wrote up here, notice that every time we get a request, we create a User object and a UserService object, right?

So, as you keep sending requests and requests and requests, is our code going to keep creating objects and creating objects, and we’re going to have more and more and more objects in the heap? ** As shown below.

What happens when the heap is full?

So let me ask you a question, heap memory is a piece of memory, can it put objects indefinitely?

Of course not, when you have more and more objects, too many, will fill up the memory space, filled up after he can not put new objects, this time what to do?

This triggers a garbage collection, in which the JVM process surreptitiously opens a garbage collection thread that looks at the heap, senses that it is almost full, and cleans up some of its objects. This is called garbage collection, as shown in the following figure.

But each garbage collection, there is a problem, because he want to clean up some objects, so tend to clean up the object, avoid you again to create a new object, or just like your mother to clean your room, people in to clean up the garbage, you also eat the rubbish into the ground, your mother didn’t spank you just strange, right? So garbage collection usually stops the JVM process from creating new objects, as shown below.

So in garbage collection to stop running JVM process of this period, will lead to a problem, that is your users to send request, no processing, and yes, this time the user will feel every time send a request that was stuck, stuck with no return, the system performance is in a poor state, the following figure.

How do you optimize system performance with singleton patterns?

So this is where the question comes in, back to the main body of this article, which is how do you optimize system performance with singletons?

Actually according to the above problem, a lot of friends may have discovered that if you want to optimize system performance, there is a key point is to create fewer objects, avoid heap memory frequently with, also can avoid frequent garbage collection, can avoid frequent JVM process pause more, thus avoiding frequent system requests, no response.

** So how to create fewer objects? ** Singleton is a good way to do this. For us, we can make the UserService object be created only once. Instead of repeating the creation of the object with each request, we can make the object be created only once.

@RestController("/user")
public class Controller {
  
  private UserService userService;
  
  @RequestMapping("/create")
  public Response create(CreateUserRequest request) {
    User user = new User(request);
    
    UserService userService = UserSerivce.getInstance();
    userService.add(user);
    
    returnResponse.success(); }}public class UserService {
  
  private UserService(a) {}
  
  private static class Singleton {
    static UserService userService = new UserService(); 
  }
  
  public static UserService getInstance(a) {
    returnSingleton.userService; }}Copy the code

As you can see in the code above, we define a private static inner class Singleton in UserService. In the Singleton, we define a static variable UserService object. In this case, the Singleton class will only be loaded once. A static variable UserService object is instantiated only when the class is loaded. Each subsequent call to getInstance() will fetch the only object directly.

This is the singleton pattern of a kind of writing, also is a kind of writing commonly used in the enterprise development, after using the singleton pattern, can greatly reduce the number of objects we create, avoid frequent heap memory with frequent garbage collection, frequent JVM process pause request performance influence, so often can help us to better improve the system performance.

END

Scan code for free 600+ pages of Huisei teachers original fine articles summary PDF

Summary of original technical articles