Различные приемы DEBUG в IDEA

Java

Функции отладки различных IDE на Java предоставляются через Java.Java Platform Debugger Architecture (JPDA)быть реализованным.

С помощью функции отладки вы можете легко отладить программу и быстро смоделировать/найти ошибки в программе.

Хотя функция отладки Intellij Idea похожа на Eclipse, она все же намного лучше, чем Eclipse, с точки зрения опыта.

Отладка наиболее часто используемый способ перехода к следующему шагу, следующей точке останова (Breakpoint), просмотру значения нескольких выполняемых операций; но в дополнение к этим IDE также предоставляет некоторые «расширенные» функции, которые могут помочь нам легче отлаживаться,

Java8 Streams Debug

Отличительной особенностью Java 8 является то, что Stream — это концепция, полностью отличающаяся от InputStream и OutputStream в пакете java.io. Stream в Java 8 — это усовершенствование функции объекта коллекции (Collection), которое фокусируется на различных очень удобных и эффективных операциях агрегации (aggregate Operations) или массовых операциях с данными (bulk data Operations) над объектами коллекции.

IntStream.iterate(1, n -> n + 1)
                .skip(100)
                .limit(100)
                .filter(PrimeFinder::isPrime)//检查是否是素数
                .forEach(System.out::println);

Приведенный выше код представляет собой обычное использование потоков, которые сортируют коллекцию и преобразуют значения. Idea также предоставляет возможность анализировать процесс потоков



Изменить поток выполнения программы

В процессе отладки в целом программа может выполняться нормально. Однако в некоторых случаях необходимо динамически изменять процесс выполнения.В это время слишком неудобно изменять код.К счастью, Idea предоставляет некоторые функции для динамического изменения процесса выполнения программы, что позволяет нам отлаживать гибко.

Возврат к предыдущему фрейму стека / удаление текущего фрейма стека / «удаление фрейма»

Когда у нас дрожат руки при отладке, мы нажимаем следующий шаг заранее или неправильно, что приводит к пропущенным точкам останова. На этом этапе вы можете использовать функцию Drop Frame, предоставляемую Idea, чтобы вернуться к предыдущему кадру стека.

Стек виртуальной машины описывает модель памяти Model of Java-метода выполнения: каждый метод создаст кадр стека (кадр стека) [иллюстрации] в то же время выполнения для хранения информации, такой как локальная таблица переменных, стек операнда, динамическая ссылка, выход и т. д. Процесс каждого метода от вызова к завершению выполнения соответствует процессу кадра стека, который подталкивается в стек в стеке виртуальной машины.

На самом деле не только Java, но и модель выполнения методов других языков программирования представляет собой стековую структуру, а выполнение метода соответствует операции push/pop.

Например, в следующем коде, когда метод выполняется один раз, в кадре стека есть два метода.

В этот момент, после нажатия кнопки Drop Frame, данные в верхней части стека будут удалены и возвращены в положение перед вызовом метода журнала.

Примечание. Хотя Drop Frame прост в использовании, некоторые необратимые проблемы могут возникнуть после Drop Frame, например операции класса ввода-вывода или измененные общие переменные, которые нельзя откатить, поскольку эта операция удаляет только кадр стека на вершине стека, Не совсем "бег назад"

Принудительный возврат

Когда метод длинный или информация о шаге достигает менее важного метода и хочет его пропустить, вы можете использовать функцию принудительного возврата, чтобы принудительно завершить метод.

Примечание: Force Return отличается от Step Out. Step Out — это выход из текущего шага или выполнение кода в методе, а Force Return — принудительное завершение метода напрямую, пропуск всего кода после метода и возврат напрямую. Например, в следующем коде, когда используется принудительный возврат, println в методе оценки не будет выполняться.

Когда принудительный возврат метода имеет возвращаемое значение (не void), принудительный возврат также должен указывать возвращаемое значение.

вызвать исключение

Когда вызываемый метод может генерировать исключение, а вызывающему объекту необходимо обработать исключение, метод может напрямую генерировать исключение без изменения кода.

Ниже приведен псевдокод, который имитирует отправку запроса и автоматически повторяет попытку с течением времени.

Когда метод выполняется для sendPacket, вы можете выполнить операцию Throw Exception, досрочно завершить метод и сгенерировать указанное исключение.

После того, как вызывающая сторона получает исключение, она может выполнить логику повтора в catch, поэтому нет необходимости модифицировать программу для имитации исключения, что очень удобно.

Отладка запущенного процесса JVM (присоединение к процессу)

Когда приложение не может работать в IDEA, я хочу отлаживать эту запущенную программу, вы можете передать функцию «Присоединить к процессу», которая может отлаживать программу при отладке, конечно, предпосылкой является обеспечение того, чтобы этот работающий код процесса JVM согласовывался с код в идее

Этот сценарий на самом деле довольно распространен.Например, когда вы хотите отлаживать исполняемый файл jar Springboot или отлаживать процессы, которые развертываются и выполняются независимо, например исходный код tomcat, очень удобно использовать Присоединение к процессу.Вы можете использовать среды, отличные от Идея + Идея.Отладка кода

На самом деле эта функция доступна и в C/C++ GDB, это только работающая программа Debug, и Intellij Clion ее тоже поддерживает.

Удаленная отладка

Удаленная отладка — это функция, предоставляемая JVM, аналогичная описанной выше функции «Присоединение к процессу», за исключением того, что процесс изменился с локального на удаленный.

Например, в нашей программе локально нет проблем, но есть проблема на сервере, например, локальный MacOs, сервер Centos, и некоторые ошибки появляются из-за разных сред, в это время мы можем отлаживать через функцию удаленной отладки.

Если вы хотите включить удаленную отладку, вам необходимо добавить следующие параметры в скрипт запуска удаленного процесса JVM:

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005

Параметр приостановки указывает, запущен ли процесс JVM в режиме "приостановки". Если он запущен в режиме "приостановки", процесс JVM будет заблокирован и не будет продолжать выполняться до тех пор, пока к процессу не подключится удаленный отладчик.

Этот параметр очень полезен, например, наша проблема возникает во время запуска JVM (например, в процессе загрузки/инициализации Spring), нам нужно установить приостановку на y, чтобы процесс JVM ждал завершения соединения удаленной отладки в Ide, прежде чем продолжающийся бег. В противном случае удаленная JVM уже какое-то время работает, а Ide's Debugger только подключился, а точка останова давно пропущена.

После того, как удаленный процесс JVM настроен в режиме отладки и запущен, вы можете подключиться в Idea и создать новую удаленную конфигурацию на панели «Конфигурации запуска/отладки» в Idea:

Затем настройте хост/порт, нажмите «Применить», чтобы сохранить

Наконец, сначала запустите удаленный процесс JVM, а затем отладьте его в Idea, чтобы запустить конфигурацию, которую вы только что настроили.

Советы: под удаленной отладкой, ответ будет медленным из-за накладных расходов сети, и он приведет к суспензии удаленной программы. Пожалуйста, найдите среду, где никто не использует ее.

Отладка в условиях многопоточности

Многопоточные программы сложнее писать, а если быть точным, то их сложно отлаживать, небрежное выполнение приведет к различным ошибкам из-за проблем с безопасностью потоков, и эти ошибки может быть трудно воспроизвести. Поскольку планирование потоков операционной системы находится вне нашего контроля, ошибки многопоточных программ очень случайны, и если возникает проблема, ее трудно найти; наша программа может быть нормальной в 99,99% случаев, но последние 0,01% также могут привести к серьезным ошибкам.

Наиболее распространенная проблема с безопасностью потоков — это состояние гонки, которое может возникнуть, когда некоторые данные изменяются несколькими потоками одновременно.

Например, следующий процесс, в нормальных условиях, программа не проблема

Когда возникает проблема конкуренции, другие потоки планируются между операциями чтения и записи одного потока, и данные будут неправильными.

Ниже приведен пример кода.Хотя общие данные a представляют собой synchronizedList, это не гарантирует, что addIfAbsent является атомарной операцией, так как contains и add — это два синхронизированных метода, а промежуток выполнения между двумя методами все еще может быть изменен другими потоки.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ConcurrencyTest {
    static final List a = Collections.synchronizedList(new ArrayList());

    public static void main(String[] args) {
        Thread t = new Thread(() -> addIfAbsent(17));
        t.start();
        addIfAbsent(17);
        t.join();
        System.out.println(a);
    }

    private static void addIfAbsent(int x) {
        if (!a.contains(x)) {
            a.add(x);
        }
    }
}

Если этот код проводить Debug, после Step Over (Next) следующим шагом является область действия всего процесса, а не текущего потока. То есть после отладки следующий шаг, вероятно, будет вставлен в другой поток и выполнит изменения, это небезопасно, так как общие данные, это может возникнуть проблема с добавлением элемента 17.

Однако вышеперечисленные проблемы возможны, и их трудно воспроизвести при реальной отладке. Отладка идеи может установить степень детализации приостановки на потоки, а не на весь процесс.

После того, как для Suspend установлено значение Thread, как показано на рисунке ниже, нажмите точку останова на строке a.add, а затем запустите программу в режиме отладки, основной поток и вновь созданный поток будут зависать в методе addIfAbsent, мы можем Отладка в потоках Idea Switch на панели

В этот момент поток MAIN и подпоток вызвали метод Contains и вернули false, зависли в строке .add, готовые добавить 17 к

После выполнения следующего шага основной поток успешно добавил 17 в коллекцию.

В это время при переключении на поток Thread-0 он все еще зависает на строке a.add(x), но в наборе a уже есть элементы 17, но поток Thread-0 будет продолжать добавлять, и набор a будет повторяется после доп.Элемент 17, вызывая ошибку в программе

Как видно из приведенного выше примера, в процессе отладки многопоточных программ функция Suspend программы Idea Debug может использоваться для простой имитации проблемы многопоточной конкуренции, что очень удобно для написания или отладки многопоточных программ. программы.

Ссылаться на

Оригинальность непростая, пожалуйста, перепечатайте в начале статьи известный источник и автора. Если моя статья оказалась для вас полезной, пожалуйста, поставьте лайк и соберите, чтобы поощрить поддержку.