JavaRush /Java блог /Random UA /Кава-брейк #94. Огляд п'яти статичних аналізаторів Java-к...

Кава-брейк #94. Огляд п'яти статичних аналізаторів Java-коду. Помилки в купі та стіковій пам'яті Java

Стаття з групи Random UA

Огляд п'яти статичних аналізаторів Java-коду

Джерело: DZone Розробникам часто потрібні різні програми, у тому числі статичні аналізатори коду, які можуть знайти та виправити помилковий код на ранніх етапах розробки. Незважаючи на те, що рев'ю коду є незамінним помічником у цій справі, іноді кількість коду, яку рецензенти мають переглянути і продумати, жахає. На це йде багато часу та сил. Також це призводить до того, що рецензенти часто звертають увагу лише на критичні для програми фрагменти коду. Тоді як інструменти статичного аналізу перевіряють весь код однаковою точністю. Кава-брейк #94.  Огляд п'яти статичних аналізаторів Java-коду.  Помилки в купі та стіковій пам'яті Java - 1Я зібрав кілька аналізаторів коду, сумісних із IntelliJ IDEA. Сподіваюся, це допоможе вам у вашій роботі.

Вбудований аналізатор IntelliJ IDEA

Статичний аналізатор Java-коду, вбудований в IntelliJ IDEA, нічим не поступається спеціалізованим інструментам статичного аналізу. Пошук підозрілих, захаращених або некоректних фрагментів коду здійснюється за допомогою різних методів статичного аналізу: аналізу потоку даних та зіставлення із зразком. IntelliJ IDEA має велику кількість інспекцій. Правду кажучи, багато з них не завжди точно повідомляють про помилку. Швидше вказують на недбалість у коді або можливість змінити її акуратною альтернативою. Трохи вивчивши “Inspections → 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 Community Edition.

SonarJava

SonarJava – це статичний аналізатор коду для Java від SonarSource. До переліку його функцій входить:
  • 150+ правил виявлення помилок;
  • 350+ правил розпізнавання запахів коду;
  • 40+ правил виявлення потенційних уразливостей ;
  • Інтеграція з Maven, Gradle, Ant, Eclipse, IntelliJ IDEA, VS Code;
  • Можливість розширення за допомогою налаштованих діагностичних правил;
  • Спеціалізований інструмент SAST: більшість діагностичних правил складено відповідно до CWE , CERT , OWASP .
Запускати аналіз можна як у різних IDE (через плагін SonarLint ), так і окремо в SonarQube . SonarLint вміє працювати пліч-о-пліч із вбудованим аналізатором коду IntelliJ IDEA. Якщо навести курсор на виділений фрагмент коду, можна побачити попередження від обох аналізаторів: Кава-брейк #94.  Огляд п'яти статичних аналізаторів Java-коду.  Помилки в купі та стіковій пам'яті Java - 6Звичайно, ви можете переглянути попередження в окремому вікні: Кава-брейк #94.  Огляд п'яти статичних аналізаторів Java-коду.  Помилки в купі та стіковій пам'яті Java - 7В цілому, можливість запускати SonarJava по-різному робить його привабливим. Це дає розробникам свободу вибору інструмента під час написання коду.

FindBugs / SpotBugs

На жаль, 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-Studio

PVS-Studio базується на бібліотеці з відкритим вихідним кодом Spoon. Він отримує вихідний код як вхідні дані і будує добре спроектовану модель AST з семантичною інформацією. На основі цієї моделі в аналізаторі використовуються такі сучасні методики, як:
  • Аналіз потоку даних;
  • Символічне виконання;
  • Анотації методів;
  • Аналіз на основі шаблонів.
На даний момент аналізатор використовує більше 105 діагностичних правил, які виявляють різні недоліки коду. Вони включають виправлення помилок, перейменування null-посилань, недосяжний код, індекс масиву поза межами, порушення використання договору методу та інші помилки. Ви можете дізнатися всі можливості діагностичних правил тут . Основні функції PVS-Studio:
  • Аналізатор спрямовано пошук реальних помилок;
  • Крім версії CLI, є інтеграція з IntelliJ IDEA, Maven, Gradle, Jenkins, SonarQube;
  • Можливість запуску аналізатора в інкрементальному режимі;
  • Аналізатор виявляє потенційні проблеми сумісності з Java SE API під час перенесення проекту з Java 8 більш свіжі версії;
  • PVS-Studio конвертує звіт у різні зручні для користувача формати: JSON, XML, HTML, TXT;
  • Спеціалізований інструмент SAST: більшість діагностичних правил складено відповідно до CWE , CERT , OWASP .

PMD

PMD – це статичний аналізатор із відкритим вихідним кодом. Він виявляє типові помилки розробки: змінні, що не використовуються, порожні блоки, створення непотрібних об'єктів та інші проблеми. Як вхідні дані аналізатор використовує вихідний код. Зараз PMD аналізує один вихідний файл протягом одного процесу роботи, що накладає обмеження на повноту аналізу. Автори PMD радять збирати проект перед аналізом. Це дозволяє витягувати інформацію про типи, що використовуються в коді, що аналізується. Основні функції PMD:
  • Інтеграція з різними IDE (IntelliJ IDEA, Eclipse, NetBeans) та системами збирання (Maven, Gradle, Ant);
  • Підтримує різні формати звітів аналізатора: SARIF, CSV, IDEA, JSON, текст (за замовчуванням), XML, HTML, TextColor тощо;
  • Має понад 300 шаблонів діагностичних правил. Категорії: стиль кодування, найкращі практики, помилки, багатопоточність, продуктивність тощо;
  • Поставляє CPD (детектор копіювання-вставки) разом із 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 Heap Space

Ця помилка виникає, коли Java не вдалося виділити новий об'єкт в області пам'яті купи.

GC Overhead Limit Exceeded

Програма 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 містить посилання на наші згенеровані рядки, тому збирач сміття не може видалити згенеровані рядки з пам'яті, а намагається видалити будь-яке інше сміття у додатку. Але цього не достатньо.

Запрошений розмір масиву перевищує межу віртуальної машини (Requested Array Size Exceeds VM Limit)

Помилка виникає при спробі виділити масив, коли місця в купі недостатньо.
public class OutOfMemoryErrorDemo {
    public static void main(String[] args) {
        // we try to create too long array
        long[] array = new long[Integer.MAX_VALUE];
    }
}

Метапростір (Metaspace)

Виняток видається з цим повідомленням, коли в області метапростору немає місця для інформації про дані класу.

Немає місця для підкачування (Request Size Bytes for Reason. Out of Swap Space?)

Помилка з'являється, коли не вдалося виділити пам'ять у своїй купі або її розмір недостатній.

reason 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);
    }
}
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ