This article has participated in the weekend learning program, click the link to see more details: juejin.cn/post/696572…

First, it’s a sad story about underlying JVM optimization. Think of the first time encounter this kind of problem of meng force, should be an old saying: books to use square hate less!

At about 8 o ‘clock in the evening, the operation and maintenance group reported that a large number of users could not receive SMS messages. Log in Kibana to search the corresponding Error log, and found a large number of out-of-bounds subscript exceptions

At the time… Online issues have been fixed. However, problems can not find the cause of the output of the problem, or the next time there may be a recurrence

Since it is not convenient to conduct log analysis on ELK, it is difficult to conduct statistical analysis at different latitudes according to corresponding anomalies. Therefore, I contacted o&M students to pull down Info and Error logs of the day when the fault occurred for offline analysis

According to log analysis, there are two kinds of abnormal outputs, one is with stack information, such as:

java.lang.ArrayIndexOutOfBoundsException: -1. Omit stack informationCopy the code

The other, which is a bit spooky, has only exceptions and no corresponding stack information

java.lang.ArrayIndexOutOfBoundsException: null
Copy the code

The first problem is relatively easy to locate, according to the exception stack information, locate the specific code, directly repair, difficult in the second

In fact, these two are an anomaly, look back at the partner will understand. Everything we’ve done since then has been about trying to figure out two things

  • Why does the exception message print null
  • Why is the stack message not printed out

JVM Fast Throw

What is a Fast Throw?

In plain English, when some exception types (null Pointers, out-of-bounds subscripts, arithmetic operations, etc.) If a fixed location in the code is thrown multiple times, the HotSpot VM will simply throw a preassigned exception object of a matching type. Both message and stack Trace for this exception object are empty

See here I believe readers have understood why the same exception, the printed log is not the same content. If the JVM throws a preallocated exception, the message and stack trace will be swallowed

The compiler in the server VM now provides correct stack backtraces for all “cold” built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace. To disable completely the use of preallocated exceptions, use this new flag: -XX:-OmitStackTraceInFastThrow.

This is described in the JDK 1.5 release documentation, and the reason for this optimization is to improve performance. When the same exception is thrown multiple times at the same location, the compiler recompiles the method. After recompilation, the compiler may choose a faster strategy using a preallocated exception that does not provide a stack trace

If you want to close this dysfunction of the early allocation mechanism, can use – XX: – OmitStackTraceInFastThrow. Readers who are interested can check out the release description: https://sourl.cn/PMzVkC

In addition, according to the SOURCE code of the JVM, the Fast Throw mechanism currently supports five exceptions, as shown in the screenshot below

To simulate the Fast Throw

The above is all the theory part, this chapter uses the code to practice

List<String> list = new ArrayList();
for (int j = 0; j < 10000; j++) {
    try {
        list.get(-1);
    } catch (Exception ex) {
        int length = ex.getStackTrace().length;
        System.out.println(String.format("Error exception :: %s stack length :: %s", ex, length)); }}Copy the code

The Fast Throw is still valid in Java8

It is best not to turn this feature off without special circumstances. The Fast Throw mechanism can save a lot of performance costs if a large number of requests Throw exceptions in the same code because of a BUG in the program. As shown in the single-thread running Demo, the more exception calls, the greater the difference in performance

Open the Fast Throw Closed Fast Throw
10w 1004ms 3547ms
100 w 6193ms 30928ms
500w 37492ms .

If the online environment triggers the Fast Throw mechanism, you can locate the cause of the problem by tracing the logs forward to the same location with the same exception

“Said

In a word, refactoring is risky, and go live with caution

For the reconstruction of public functions, it is necessary to include a full range of test cases, to take into account the output background of possible problems to the extreme, or to explain the demand background with colleagues around us, we think together, can greatly avoid the output of extreme problems

The necessary pressure test is very important, which can be very good to show the flow of large problems in advance exposed

The meaning of failure, good and bad, bad point we all understand; Good point of nature is the accumulation of online problem troubleshooting experience, so that the back of the company sister encountered the same problem, Shouting: sister, let go of the BUG, let me come!

Creation is not easy, the article see here if it helps, you can point to a concern to support, WISH well. See you next time!


Recommend 👍 : five minutes literacy: the story of the evolution process of the DataSource | learn over the weekend

Recommended 👍 : a factory interview: How to use SPI mechanism gracefully | weekend learning