JavaRush /Java Blog /Random EN /Coffee break #94. Review of five static Java code analyze...

Coffee break #94. Review of five static Java code analyzers. Java heap and stack memory errors

Published in the Random EN group

Review of five static Java code analyzers

Source: DZone Developers often require various programs, including static code analyzers, that can find and fix erroneous code early in development. While code reviews are an invaluable tool in this endeavor, sometimes the amount of code reviewers have to review and review is daunting. This takes a lot of time and effort. This also leads to the fact that reviewers often pay attention only to code fragments that are critical for the operation of the program. Whereas static analysis tools check all code with the same accuracy. Coffee break #94.  Review of five static Java code analyzers.  Java heap and stack memory errors - 1I've put together several code analyzers that are compatible with IntelliJ IDEA. I hope this helps you in your work.

Built-in IntelliJ IDEA analyzer

The static Java code analyzer built into IntelliJ IDEA is in no way inferior to specialized static analysis tools. The search for suspicious, cluttered or incorrect code fragments is carried out using various static analysis methods: data flow analysis and pattern matching. IntelliJ IDEA has a large number of inspections. In truth, many of them do not always accurately report the error. Rather, they indicate sloppiness in the code or the possibility of changing it with a neat alternative. After studying “Inspections → Java” a little, I noticed one thing. Inspections in the categories of probable errors, numerical problems, and serialization problems are more likely to find real errors. In any case, you must conduct the tests yourself and determine which ones will be useful for your project. Because static analysis is performed in code editing mode, in IntelliJ IDEA you can fix errors within seconds of them occurring. The editor immediately highlights the incorrect code fragment. Coffee break #94.  Review of five static Java code analyzers.  Java Heap and Stack Memory Errors - 2It's really convenient and cool! In addition, if you use the “Alt + Enter” combination on a selected piece of code, you can select one of the options to fix the error through the context menu: You can Coffee break #94.  Review of five static Java code analyzers.  Java Heap and Stack Memory Errors - 3also find out the reason for running a particular inspection. In some cases, this reduces search time: Coffee break #94.  Review of five static Java code analyzers.  Java Heap and Stack Memory Errors - 4You can run the analysis manually by selecting “Analyze → Check Code”. Or you can run an individual check using “Analyze → Run check by name”. Before doing this, specify the scope of analysis (for a project, module or individual file). When you run an analysis this way, some inspections become available that do not work in edit mode due to complexity. After analysis, the results will be grouped by category/directory in a separate window. From this window you can navigate to a specific validation trigger: Coffee break #94.  Review of five static Java code analyzers.  Java Heap and Stack Memory Errors - 5IntelliJ only allows you to save the analysis result in HTML and XML formats. Unfortunately, in my opinion, it is most convenient to work with detected problems in the IDE itself. Note. Most of the static analyzer features are available in the free IntelliJ IDEA Community Edition.

SonarJava

SonarJava is a static code analyzer for Java from SonarSource. The list of its functions includes:
  • 150+ error detection rules;
  • 350+ rules for recognizing code smells;
  • 40+ rules for detecting potential vulnerabilities ;
  • Integration with Maven, Gradle, Ant, Eclipse, IntelliJ IDEA, VS Code;
  • Expandable with custom diagnostic rules;
  • Specialized SAST tool: most diagnostic rules are compiled in accordance with CWE , CERT , OWASP .
You can run the analysis both in various IDEs (via the SonarLint plugin ) and separately in SonarQube . SonarLint can work side by side with the built-in IntelliJ IDEA code analyzer. If you hover over a highlighted piece of code, you can often see warnings from both analyzers: Coffee break #94.  Review of five static Java code analyzers.  Java Heap and Stack Memory Errors - 6Of course, you can view the warning in a separate window: Coffee break #94.  Review of five static Java code analyzers.  Java Heap and Stack Memory Errors - 7Overall, the ability to run SonarJava in different ways makes it attractive. This gives developers the freedom to choose a tool when writing code.

FindBugs/SpotBugs

Unfortunately, FindBugs has not been updated for a long time; the last stable release was released back in 2015. But we still remember and use it, since it is perhaps the most famous free static Java code analyzer. If you ask a Java developer about static analysis, they'll probably immediately think of FindBugs. The open source analyzer SpotBugs became a logical continuation of the abandoned FindBugs. It has all the advantages and disadvantages of FindBugs. Time will tell whether this is good or bad. In the meantime, the analyzer community is actively developing it. Key features of SpotBugs:
  • 400+ error detection rules;
  • Integration into Ant, Maven, Gradle, Eclipse, IntelliJ IDEA;
  • Expandable with custom diagnostic rules.
To find suspicious code, the same methodologies are used: pattern matching and data flow analysis. The analyzer detects various types of errors that are related to multithreading, performance, vulnerabilities, code obfuscation, and so on. In IntelliJ IDEA, the alert window looks like this: Coffee break #94.  Review of five static Java code analyzers.  Java Heap and Stack Memory Errors - 8Alerts can be grouped by category, class, directory, and confidence level. You can simultaneously view alerts and documentation for any diagnostic rule. The analysis is started manually. After analysis, all problematic code fragments are highlighted along with other warnings from IntelliJ IDEA and SonarLint. However, there is a problem. You must rerun the analysis to update the warnings to reflect the changes you made to the file. There are also many advisory warnings, so the analyzer must be configured before active use.

PVS-Studio

PVS-Studio is based on the open source library Spoon. It takes the source code as input and builds a well-designed AST model with semantic information. Based on this model, the analyzer uses such modern techniques as:
  • Data flow analysis;
  • Symbolic performance;
  • Method annotations;
  • Pattern-based analysis.
Currently, the analyzer uses more than 105 diagnostic rules that identify various code flaws. These include typo corrections, renaming null references, unreachable code, out-of-bounds array index, violation of method contract usage, and other errors. You can find out all the diagnostic rules capabilities here . Main functions of PVS-Studio:
  • The analyzer is focused on finding real errors;
  • In addition to the CLI version, there is also integration with IntelliJ IDEA, Maven, Gradle, Jenkins, SonarQube;
  • Ability to run the analyzer in incremental mode;
  • The analyzer identifies potential compatibility issues with the Java SE API when migrating a project from Java 8 to more recent versions;
  • PVS-Studio converts the report into various user-friendly formats: JSON, XML, HTML, TXT;
  • Specialized SAST tool: most diagnostic rules are compiled in accordance with CWE , CERT , OWASP .

PMD

PMD is an open source static analyzer. It identifies common development errors: unused variables, empty blocks, creation of unnecessary objects and other problems. The analyzer uses source code as input. Currently, PMD analyzes one source file per process, which imposes limitations on the completeness of the analysis. The PMD authors advise assembling the project before analysis. This allows you to extract information about the types used in the code being analyzed. Main functions of PMD:
  • Integration with various IDEs (IntelliJ IDEA, Eclipse, NetBeans) and build systems (Maven, Gradle, Ant);
  • Supports various analyzer report formats: SARIF, CSV, IDEA, JSON, text (default), XML, HTML, TextColor and so on;
  • Has more than 300 diagnostic rule templates. Categories: coding style, best practices, bugs, multithreading, performance and so on;
  • Provides a CPD (Copy-Paste Detector) along with a PMD that detects duplicates in the code.
If we look at all the diagnostic rules, PMD is more focused on solving coding style problems and catching obvious errors. Diagnostic rules may conflict with each other, so they must be configured before using the analyzer. You can also run the analysis through a plugin for IntelliJ IDEA, but you cannot select individual files for analysis. The warning window looks like this: Coffee break #94.  Review of five static Java code analyzers.  Java Heap and Stack Memory Errors - 9In my opinion, working with warnings is not very convenient, since they cannot be grouped by files and non-obvious messages. They only appear when you hover over the warning.

Conclusion

Of course, in addition to the analyzers discussed above, there are other solutions. There are both paid (Coverity, Klockwork, JArchitect) and free (Error Prone, Infer, Checkstyle) programs. They all focus on one thing: preventing incorrect or potentially buggy code from reaching production. I have no right to judge which analyzer is better suited for this task. But analyzers that develop data flow analysis and symbolic execution are more likely to find a real bug in the code. If you choose a static analyzer, pay attention to:
  • integration into various IDEs;
  • integration into assembly systems;
  • ease of launching the analyzer on the server;
  • the ability to detect errors in code editing mode;
  • the ability to conveniently work with warnings;
  • SAST orientation;
  • percentage of false positives;
  • complexity of the configuration.
  • The combination of all the pros and cons will lead you to the number of static analyzers that you consider to be the best.
Note: I provided examples with integration into IntelliJ IDEA, since I often use it.

Java heap and stack memory errors

Source: DZone We'll now look at the main errors that can occur in Java heap or stack memory, but first let's remember what these two terms mean.
  • Heap memory is a special area of ​​memory in which java objects are stored.
  • Stack memory is an area of ​​temporary memory for storing variables when calling a method.
The main exception that describes a heap memory problem is java.lang.OutOfMemoryError . Coffee break #94.  Review of five static Java code analyzers.  Java Heap and Stack Memory Errors - 10

Java Heap Space

This error occurs when a Java program fails to allocate a new object in a heap memory area.

GC Overhead Limit Exceeded

A Java program spends too much time doing garbage collection. This error appears when garbage collection takes up 98% of the program's time and recovers less than 2% of the memory space.
public class OutOfMemoryErrorDemo {
    public static void main(String[] args) {
        int i = 0;
        List<String> stringList = new ArrayList<>();
        while (i < Integer.MAX_VALUE) {
            i++;
            String generatedString = new String( "Some string generated to show out of memory error example " + i);
            stringList.add(generatedString);
        }
    }
}
Here stringList contains a reference to our generated strings, so the garbage collector cannot remove the generated strings from memory, but tries to remove any other garbage in the application. But this is not enough.

Requested Array Size Exceeds VM Limit

The error occurs when you try to allocate an array when there is not enough space in the heap.
public class OutOfMemoryErrorDemo {
    public static void main(String[] args) {
        // we try to create too long array
        long[] array = new long[Integer.MAX_VALUE];
    }
}

Metaspace

An exception is thrown with this message when there is no room in the metaspace region for class data information.

No swap space (Request Size Bytes for Reason. Out of Swap Space?)

The error appears when memory could not be allocated on the native heap or its size is insufficient.

reason stack_trace_with_native_method

A native Java interface or native method failed to allocate memory on the heap. StackOverFlowError - when there are too many method calls. Usually an exception is thrown by a method that has recursion inside it.
public class StackOverFlowErrorDemo {

    public static void main(String[] args) {
        recursiveMethod(2);
    }

    public static int recursiveMethod(int i) {
      	// it will never stop and it allocates all stack memory
        return recursiveMethod(i);
    }
}
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION