编程知识 cdmana.com

Never use this version of JDK in a production environment. Isn't that right? Memory overflow again! It's about to crack! (recommended Collection)

Hello everyone , I'm glacier ~~

lately , A little friend told me : The program he wrote had no problem in the test environment , However, memory overflow occurs frequently when it is sent to the production environment , This problem has bothered him for more than a week . So , At the weekend, I began to help him check all kinds of problems .

If the article helps you a little , Like it, guys 、 Collection 、 Comment and share , Let's go ~~

The question of my partner

 Insert picture description here

Problem determination

The whole process of troubleshooting is quite time-consuming , here , I'll just go straight to the problem of positioning . Back , I will write a separate article on the detailed troubleshooting process !

In the process of troubleshooting , I found that this little friend used JDK still 1.6 edition . Start , I didn't think so much , Continue to check the code he wrote , Didn't find any problems . But once the production environment is started , It was not long before ,JVM It throws a memory overflow exception .

This is strange , What's going on ?

Start the program with a reasonable JVM Parameters , Problems still exist ...

Can't , Keep looking at his code ! Unintentionally , I found that in the code he wrote , Used a lot String Class substring() Method to intercept the string . therefore , I followed JDK Check the parameters passed in with the code in .

This is a view of inadvertently clicking in , Found the problem !!

JDK1.6 in String Class pits

Through the analysis of , I found JDK1.6 in String A big pit of class ! Why is it a pit ? Because of its substring() The method will make people miserable ! Not much said , So let's see JDK1.6 Medium String Class substring() Method .

public String substring(int bedinIndex, int endIndex){
    
    if(beginIndex < 0){
    
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if(endIndex > count){
    
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    if(beginIndex > endIndex){
    
          throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    }
    return ((beginIndex == 0) && (endIndex == count)) ? this : new String(offset + beginIndex, endIndex - beginIndex, value);
}

Next , Let's see JDK1.6 Medium String A construction method of class , As shown below .

String(int offset, int count, char[] value){
    
    this.value = value;
    this.offset = offset;
    this.count = count;
}

notice , here , I believe the careful partner has found the problem , The culprit of the problem is the following line of code .

this.value = value;

stay JDK1.6 in , Use String When the constructor of class creates a substring , It's not just a simple copy of what you need , But every time I put the whole value Quote in . If the original string is large , Even if this string is no longer applied , The memory allocated by this string will not be released . This is also my conclusion after a long time of analyzing the code , It's just too much !!

Now that the problem is found , Then we have to solve this problem .

upgrade JDK

since JDK1.6 Medium String There is such a huge pit , The most direct and effective way is to upgrade JDK. therefore , I explained the situation to my little friend , Let him JDK Upgrade to JDK1.8.

alike , Let's also have a look at JDK1.8 Medium String Class substring() Method .

public String substring(int beginIndex, int endIndex) {
    
    if (beginIndex < 0) {
    
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > value.length) {
    
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    int subLen = endIndex - beginIndex;
    if (subLen < 0) {
    
        throw new StringIndexOutOfBoundsException(subLen);
    }
    return ((beginIndex == 0) && (endIndex == value.length)) ? this
        : new String(value, beginIndex, subLen);
}

stay JDK1.8 Medium String Class substring() In the method , Also called String Class to generate a substring , Let's take a look at this construction method , As shown below .

public String(char value[], int offset, int count) {
    
    if (offset < 0) {
    
        throw new StringIndexOutOfBoundsException(offset);
    }
    if (count <= 0) {
    
        if (count < 0) {
    
            throw new StringIndexOutOfBoundsException(count);
        }
        if (offset <= value.length) {
    
            this.value = "".value;
            return;
        }
    }
    // Note: offset or count might be near -1>>>1.
    if (offset > value.length - count) {
    
        throw new StringIndexOutOfBoundsException(offset + count);
    }
    this.value = Arrays.copyOfRange(value, offset, offset+count);
}

stay JDK1.8 in , When we need a substring ,substring A new string is generated , This string passes through the constructor's Arrays.copyOfRange Function to construct . This is no problem .

Optimize JVM Launch parameters

here , In order to better improve the performance of the system , I also helped this little friend optimize JVM Launch parameters .

Authorized by a small partner , I simply list their business scale and server configuration : The whole system adopts distributed architecture , The business services in the architecture are deployed in clusters , The average daily traffic is hundreds of millions , Average daily trading order 50W~100W, Each server node of the order system is configured as 4 nucleus 8G. Currently, the JDK Upgrade to 1.8 edition .

According to the above conditions , I gave it. JVM Optimized parameter configuration .

-Xms3072M -Xmx3072M -Xmn2048M -Xss1M -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M

as for , Why do you give the above JVM Parameter configuration , Later, I will write a separate article to specifically analyze how to proceed according to the actual business scenario JVM Parameter tuning .

After analyzing and solving the problem , The small partner's program runs smoothly in the production environment , At least there is no memory overflow yet !!

Conclusion

If you create a large object in the program , And we generated some other information based on this large object , here , Be sure to release the reference relationship with this large object , otherwise , It will bury the hidden danger of memory overflow .

JVM The goal of optimization is : Try to distribute and recycle objects in the new generation , Try not to let too many objects enter the elderly generation frequently , Avoid frequent garbage collection for older generations , At the same time, give the system sufficient memory size , Avoid frequent garbage collection by the new generation .

At the end

If you want to enter a large factory , I want a promotion and a raise , Or I'm confused about my current job , You can communicate with me by private letter , I hope some of my experiences can help you ~~

Recommended reading :

Okay , That's all for today , Like it, guys 、 Collection 、 Comment on , Get up with one button three times in a row , I'm glacier , See you next time ~~

版权声明
本文为[glacier]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/10/20211001234623678j.html

Scroll to Top