Как найти неиспользуемый / мертвый код в проектах java

какие инструменты вы используете для поиска неиспользуемого / мертвого кода в больших проектах java? Наш продукт находится в разработке в течение нескольких лет, и становится очень трудно вручную обнаружить код, который больше не используется. Однако мы стараемся удалить как можно больше неиспользуемого кода.

предложения по общим стратегиям/методам (кроме конкретных инструментов) также приветствуются.

Edit: обратите внимание, что мы уже используем инструменты покрытия кода (Clover, IntelliJ), но от них мало проку. Мертвый код все еще имеет модульные тесты и отображается как покрытый. Я думаю, что идеальный инструмент определил бы кластеры кода, которые имеют очень мало другого кода, зависящего от него, что позволяет проводить ручную проверку документов.

21 ответов


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

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

конечно, если вы идете на уровне метода, вы должны иметь в виду производительность. Для например, методы могут регистрировать только свое первое использование. Я не знаю, как это лучше всего сделать на Java. Мы сделали это в Smalltalk, который является динамическим языком и, таким образом, позволяет изменять код во время выполнения. Мы обрабатываем все методы вызовом журнала и удаляем код журнала после того, как метод был зарегистрирован в первый раз, таким образом, через некоторое время больше не происходит штрафов за производительность. Возможно, аналогичную вещь можно сделать в Java со статическими булевыми флагами...


плагин Eclipse, который работает достаточно хорошо, это Неиспользуемый Детектор Кода.

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


CodePro недавно был выпущен Google с проектом Eclipse. Это бесплатно и очень эффективно. Плагин имеет'Найти Мертвый Код ' функция с одной / многих точек входа(ы). Работает довольно хорошо.


Я удивлен ProGuard здесь не упоминается. Это один из самых зрелых продуктов.

ProGuard является бесплатным Java class file shrinker, оптимизатором, обфускатором, и preverifier. Он обнаруживает и удаляет неиспользуемые классы, поля, методы и атрибуты. Он оптимизирует байт-код и удаляет неиспользуемые инструкции. Он переименовывает остальные классы, поля и методы используя короткие бессмысленные имена. Наконец, он preverifies в обработанный код для Java 6 или для Java Micro Edition.

некоторые виды использования ProGuard:

  • создание более компактного кода, для небольших архивов кода, более быстрой передачи по сетям, более быстрой загрузки и меньшей памяти следы.
  • программы и библиотеки труднее декомпилировать.
  • список мертвого кода, поэтому его можно удалить из исходного кода.
  • ретаргетинг и preverifying существующие файлы классов для Java 6 или выше, чтобы в полной мере воспользоваться их быстрой загрузки класса.

одна вещь, которую я, как известно, делаю в Eclipse, на одном классе, - это изменить все его методы на частные, а затем посмотреть, какие жалобы я получаю. Для используемых методов это вызовет ошибки, и я верну их на самый низкий уровень доступа, который смогу. Для неиспользуемых методов это вызовет предупреждения о неиспользуемых методах, которые затем могут быть удалены. И в качестве бонуса, вы часто найти некоторые общие методы, которые могут и должны быть частными.

но это очень руководство.


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

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


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


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

Это может проявляться в коде Java многими способами:

  • загрузка классов на основе пользовательского ввода, конфигурационных файлов, записей базы данных и т. д.;
  • загрузки внешнего кода;
  • передача деревьев объектов третьей стороне библиотеки;
  • etc.

Это, как говорится, Я использую IDEA IntelliJ в качестве моей IDE выбора, и он имеет обширные инструменты анализа для findign зависимостей между модулями, неиспользуемыми методами, неиспользуемыми членами, неиспользуемыми классами и т. д. Его довольно умный тоже, как частный метод, который не называется, помечен неиспользуемым, но публичный метод требует более обширного анализа.


В Eclipse Goto Windows > Настройки > Java > Компилятор > Ошибки / Предупреждения
и измените все на ошибки. Исправьте все ошибки. Это самый простой способ. Красота в том, что это позволит вам очистить код, как вы пишете.

Скриншот Eclipse Код:

enter image description here


IntelliJ имеет инструменты анализа кода для обнаружения неиспользуемого кода. Вы должны попытаться сделать как можно больше полей / методов/классов как можно более непубличными, и это покажет больше неиспользуемых методов/полей / классов

Я бы также попытался найти дубликат кода как способ уменьшения объема кода.

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


В Structure101 точки зрения фрагмент даст список (и график зависимостей) любых "сирот" или "сирот группы "классов или пакетов, не имеющих зависимостей от" основного " кластера.


DCD не является плагином для некоторых IDE, но может быть запущен из ant или автономно. Он выглядит как статический инструмент и он может делать то, что PMD и FindBugs не могут. Я попробую.

проект С. П. выглядит сейчас мертв. Теперь есть плагин PMD, но я его не использовал.


есть инструменты, которые код профиля и предоставляют данные покрытия кода. Это позволяет увидеть (по мере запуска кода), сколько из них вызывается. Вы можете получить любой из этих инструментов, чтобы узнать, сколько сиротского кода у вас есть.


  • FindBugs отлично подходит для такого рода вещей.
  • PMD (Project Mess Detector) - еще один инструмент, который можно использовать.

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


инструменты покрытия пользователя, такие как EMMA. Но это не статический инструмент (т. е. он требует фактически запустить приложение через регрессионное тестирование и через все возможные случаи ошибок, что, ну, невозможно :))

тем не менее, Эмма очень полезна.


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

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

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

Если вы работаете в избыточной среде с балансировкой нагрузки (а если нет, то почему бы и нет?) тогда, я полагаю, это сделает смысл использовать только один экземпляр приложения и настроить балансировщик нагрузки таким образом, чтобы случайная, но небольшая часть пользователей выполнялась на инструментированном экземпляре. Если вы делаете это в течение длительного периода времени (чтобы убедиться, что вы охватили все сценарии использования в реальном мире - такие сезонные вариации), вы должны быть в состоянии увидеть, какие области вашего кода доступны в реальном мире и какие части действительно никогда не доступны и, следовательно, мертвый код.

Я никогда лично не видел, как это делается, и не знаю, как вышеупомянутые инструменты могут использоваться для инструмента и анализа кода, который не вызывается через набор тестов, но я уверен, что они могут быть.


существует проект Java - Детектор Мертвого Кода (DCD). Для исходного кода это, похоже, не работает хорошо, но для .jar file-это действительно хорошо. Кроме того, вы можете фильтровать по классу и по методу.


в NetBeans вот плагин для Netbeans детектор мертвого кода.

было бы лучше, если бы он мог ссылаться и выделять неиспользуемый код. Вы можете проголосовать и прокомментировать здесь:ошибка 181458-найти неиспользуемые общедоступные классы, методы, поля


Eclipse может показывать / выделять код, который не может быть достигнут. JUnit может показать вам покрытие кода, но вам понадобятся некоторые тесты и вы должны решить, отсутствует ли соответствующий тест или код действительно не используется.


Я нашел инструмент покрытия клевера, который кодирует инструменты и выделяет код, который используется и который не используется. В отличие от Google CodePro Analytics, он также работает для веб-приложений (по моему опыту, и я могу быть неправильным в Google CodePro).

единственный недостаток, который я заметил, заключается в том, что он не учитывает интерфейсы Java.


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