JavaRush /Java 博客 /Random-ZH /喝咖啡休息#94。五种静态 Java 代码分析器的回顾。Java堆和栈内存错误

喝咖啡休息#94。五种静态 Java 代码分析器的回顾。Java堆和栈内存错误

已在 Random-ZH 群组中发布

五种静态Java代码分析器回顾

来源:DZone 开发人员经常需要各种程序,包括静态代码分析器,可以在开发早期发现并修复错误代码。虽然代码审查是这项工作中非常宝贵的工具,但有时代码审查者必须审查和审查的数量令人望而生畏。这需要花费大量的时间和精力。这也导致了审阅者往往只关注对程序运行至关重要的代码片段。而静态分析工具以相同的准确性检查所有代码。 喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 1我整理了几个与 IntelliJ IDEA 兼容的代码分析器。我希望这对您的工作有所帮助。

内置IntelliJ IDEA分析器

IntelliJ IDEA 内置的静态 Java 代码分析器丝毫不逊于专门的静态分析工具。使用各种静态分析方法来搜索可疑、混乱或不正确的代码片段:数据流分析和模式匹配。IntelliJ IDEA 有大量的检查。事实上,他们中的许多人并不总是准确地报告错误。相反,它们表明代码中的草率或使用简洁的替代方案进行更改的可能性。在稍微学习了“检查 → Java”之后,我注意到一件事。对可能错误、数值问题和序列化问题类别的检查更有可能发现真正的错误。无论如何,您必须自己进行测试并确定哪些测试对您的项目有用。由于静态分析是在代码编辑模式下执行的,因此在 IntelliJ IDEA 中,您可以在错误发生后几秒钟内修复错误。编辑器立即突出显示不正确的代码片段。 喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 2真是方便又酷啊!此外,如果您在选定的代码段上使用“Alt + Enter”组合,则可以通过上下文菜单选择选项之一来修复错误:您还可以找出运行特定检查的原因 喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 3。在某些情况下,这可以减少搜索时间: 喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 4您可以通过选择“分析→检查代码”来手动运行分析。或者您可以使用“分析→按名称运行检查”来运行单独的检查。在执行此操作之前,请指定分析范围(针对项目、模块或单个文件)。当您以这种方式运行分析时,某些检查将变得可用,但由于复杂性而无法在编辑模式下工作。分析后,结果将在单独的窗口中按类别/目录分组。从此窗口中,您可以导航到特定的验证触发器: 喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 5IntelliJ 仅允许您以 HTML 和 XML 格式保存分析结果。不幸的是,在我看来,在 IDE 本身中处理检测到的问题是最方便的。笔记。免费的 IntelliJ IDEA 社区版提供了大多数静态分析器功能。

声纳Java

SonarJava是 SonarSource 的 Java 静态代码分析器。其功能列表包括:
  • 150+错误检测规则;
  • 350 多个识别代码异味的规则;
  • 40 多个检测潜在漏洞的规则;
  • 与 Maven、Gradle、Ant、Eclipse、IntelliJ IDEA、VS Code 集成;
  • 可通过自定义诊断规则进行扩展;
  • 专业的SAST工具:大部分诊断规则都是按照CWECERTOWASP编写的。
您可以在各种 IDE 中(通过SonarLint插件)运行分析,也可以在SonarQube中单独运行分析。SonarLint 可以与内置的 IntelliJ IDEA 代码分析器并行工作。如果您将鼠标悬停在突出显示的代码段上,您通常可以看到来自两个分析器的警告: 喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 6当然,您可以在单独的窗口中查看警告: 喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 7总体而言,以不同方式运行 SonarJava 的能力使其很有吸引力。这使得开发人员在编写代码时可以自由选择工具。

查找错误/发现错误

不幸的是,FindBugs已经很长时间没有更新了;最后一个稳定版本是在 2015 年发布的。但我们仍然记得并使用它,因为它可能是最著名的免费静态 Java 代码分析器。如果您向 Java 开发人员询问静态分析,他们可能会立即想到 FindBugs。开源分析器SpotBugs成为已废弃的 FindBugs 的逻辑延续。它具有 FindBugs 的所有优点和缺点。时间会告诉我们这是好是坏。与此同时,分析器社区正在积极开发它。SpotBugs 的主要特点:
  • 400+错误检测规则;
  • 集成到 Ant、Maven、Gradle、Eclipse、IntelliJ IDEA;
  • 可通过自定义诊断规则进行扩展。
为了查找可疑代码,使用相同的方法:模式匹配和数据流分析。该分析器可检测与多线程、性能、漏洞、代码混淆等相关的各种类型的错误。在 IntelliJ IDEA 中,警报窗口如下所示: 喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 8警报可以按类别、类、目录和置信度进行分组。您可以同时查看任何诊断规则的警报和文档。分析是手动开始的。分析后,所有有问题的代码片段以及来自 IntelliJ IDEA 和 SonarLint 的其他警告都会突出显示。然而,有一个问题。您必须重新运行分析以更新警告以反映您对文件所做的更改。还有许多建议性警告,因此分析仪必须在实际使用前进行配置。

PVS工作室

PVS-Studio基于开源库Spoon。它将源代码作为输入,并使用语义信息构建精心设计的 AST 模型。基于该模型,分析仪使用以下现代技术:
  • 数据流分析;
  • 象征性表现;
  • 方法注释;
  • 基于模式的分析。
目前,该分析器使用超过105 条诊断规则来识别各种代码缺陷。其中包括拼写错误更正、重命名空引用、无法访问的代码、越界数组索引、违反方法约定使用以及其他错误。您可以在此处找到所有诊断规则功能。PVS-Studio主要功能:
  • 分析器专注于发现真正的错误;
  • 除了CLI版本之外,还集成了IntelliJ IDEA、Maven、Gradle、Jenkins、SonarQube;
  • 能够以增量模式运行分析仪;
  • 当将项目从 Java 8 迁移到更新版本时,分析器会识别 Java SE API 的潜在兼容性问题;
  • PVS-Studio 将报告转换为各种用户友好的格式:JSON、XML、HTML、TXT;
  • 专业的SAST工具:大部分诊断规则都是按照CWECERTOWASP编写的。

PMD

PMD是一个开源静态分析器。它识别常见的开发错误:未使用的变量、空块、创建不必要的对象和其他问题。分析器使用源代码作为输入。目前,PMD 对每个进程分析一个源文件,这对分析的完整性造成了限制。PMD 作者建议在分析之前组装项目。这允许您提取有关正在分析的代码中使用的类型的信息。PMD的主要功能: 如果我们查看所有诊断规则,PMD 更专注于解决编码风格问题并捕获明显错误。诊断规则可能会相互冲突,因此在使用分析仪之前必须配置它们。您还可以通过 IntelliJ IDEA 插件运行分析,但无法选择单个文件进行分析。警告窗口如下所示: 喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 9在我看来,处理警告不是很方便,因为它们不能按文件和不明显的消息进行分组。仅当您将鼠标悬停在警告上时,它们才会出现。

结论

当然,除了上面讨论的分析器之外,还有其他解决方案。有付费(Coverity、Klockwork、JArchitect)和免费(Error Prone、Infer、Checkstyle)程序。他们都专注于一件事:防止不正确或可能有错误的代码进入生产环境。我无权判断哪种分析仪更适合这项任务。但开发数据流分析和符号执行的分析器更有可能在代码中发现真正的错误。如果选择静态分析仪,需要注意:
  • 集成到各种 IDE 中;
  • 集成到装配系统中;
  • 轻松在服务器上启动分析器;
  • 能够检测代码编辑模式中的错误;
  • 能够方便地处理警告;
  • SAST 方向;
  • 误报百分比;
  • 配置的复杂性。
  • 所有优点和缺点的结合将引导您找到您认为最好的静态分析仪的数量。
注意:我提供了集成到 IntelliJ IDEA 的示例,因为我经常使用它。

Java堆和栈内存错误

来源:DZone 现在我们将了解 Java 堆或堆栈内存中可能发生的主要错误,但首先让我们记住这两个术语的含义。
  • 堆内存是存储java对象的特殊内存区域。
  • 堆栈内存是调用方法时用于存储变量的临时内存区域。
描述堆内存问题的主要异常是java.lang.OutOfMemoryError喝咖啡休息#94。 五种静态 Java 代码分析器的回顾。 Java 堆和堆栈内存错误 - 10

Java堆空间

当Java程序无法在堆内存区域中分配新对象时,就会出现此错误。

GC 开销超出限制

Java 程序花费太多时间进行垃圾收集。当垃圾回收占用了程序 98% 的时间并且回收的内存空间少于 2% 时,就会出现此错误。
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);
        }
    }
}
这里stringList包含对我们生成的字符串的引用,因此垃圾收集器无法从内存中删除生成的字符串,但会尝试删除应用程序中的任何其他垃圾。但这还不够。

请求的数组大小超出 VM 限制

当堆中没有足够空间时尝试分配数组时会发生此错误。
public class OutOfMemoryErrorDemo {
    public static void main(String[] args) {
        // we try to create too long array
        long[] array = new long[Integer.MAX_VALUE];
    }
}

元空间

当元空间区域中没有空间用于类数据信息时,将引发异常并显示此消息。

没有交换空间(请求大小字节原因。交换空间不足?)

当无法在本机堆上分配内存或其大小不足时,会出现此错误。

原因 stack_trace_with_native_method

本机 Java 接口或本机方法无法在堆上分配内存。 StackOverFlowError - 当方法调用过多时。通常,异常是由内部具有递归的方法引发的。
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);
    }
}
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION