Ускорение Java

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

blockquote>

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно null, NullPointerException.
blockquote>

Как это исправить?

Итак, у вас есть NullPointerException. Как вы это исправите? Возьмем простой пример, который выдает NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Идентифицирует нулевые значения

. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Здесь мы видим, что исключение выбрано в строке 13 (в методе printString). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, что s имеет значение null, а вызов метода length на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когда s.length() удаляется из метода.

Трассировка, где эти значения взяты из

Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что s передается с printString(name) в методе print(), а this.name - null.

Трассировка, где эти значения должны быть установлены

Где установлен this.name? В методе setName(String). С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. ​​

Этого достаточно, чтобы дать нам решение: добавить вызов printer.setName() перед вызовом printer.print().

Другие исправления

Переменная может иметь значение по умолчанию setName может помешать ему установить значение null):

private String name = "";

Либо метод print, либо printString может проверить значение null например:

printString((name == null) ? "" : name);

Или вы можете создать класс, чтобы name всегда имел ненулевое значение :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

См. также:

Я все еще не могу найти проблему

Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).

14
задан Community 23 May 2017 в 12:24
поделиться

15 ответов

Это может казаться не важным, но существует список подсказок по скорости на сайте разработчика Android. Это работает на телефоне на нестандартном байт-коде Дальвика, но многих подсказках, перечисленных, там универсально применимы к Java в целом.

0
ответ дан 1 December 2019 в 05:52
поделиться

Во-первых: оптимизацией кода я предположил бы, что Вы сделали правильные алгоритмы и правильную реализацию алгоритмов. В этом случае Вы использовали бы профилировщика и посмотрели бы на то, как часто Ваш сборщик "мусора" (GC) собирает мусор и сколько времени он использует для того, чтобы сделать это. Затем Вы начинаете работать над опциями GC - но остерегаетесь, можно попасть в беду, если Вы не знаете то, что Вы делаете.
я предполагаю, что Вы используете Java 5/6. В этом случае я прошел бы руководство по настройке java 5 в http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html . Существует также очень очень хороший newletter на производительности Java, названной http://www.javaperformancetuning.com/ , на который можно подписаться.

Кроме этого, посмотрите на то, сколько блоков попытки/выгоды можно устранить. Посмотрите, можно ли устранить ненужный бросок Исключений.

Кэши Использования, где Вы можете, НО не переделывать, делают это.

Чтение Эффективный Java, 1-е и/или 2-е Профилировщики Выпуска

: Я использую yourkit. Это довольно хорошо для java 1.5 и выше. Можно получить персональную лицензию. Другие профилировщики также хороши также.

Точно так же, как у Вас есть модульные и интеграционные тесты, НЕ повреждает иметь некоторые тесты производительности, которые Вы выполняете как часть Ваших сборок Непрерывной интеграции (CI). Таким образом, Вы знаете, когда Вы регрессировали, особенно при использовании хорошего сервера сборки CI.

19
ответ дан 1 December 2019 в 05:52
поделиться

Вот (более старый) документ Peter Sestoft, которого стоит считать: Производительность в java. Часть совета больше, вероятно, не верна, так как Java стал намного лучше с более поздними версиями в оптимизации. Но существует все еще хороший набор драгоценных камней там, чтобы использовать и попробовать, когда профилировщик нашел что-то, что Вы не можете сделать никакого другого пути (т.е., изменить алгоритмически).

0
ответ дан 1 December 2019 в 05:52
поделиться

Java 1.6_07 + идет со своим собственным профилировщиком. Это называют Java VisualVM. Просто введите jvisualvm на командной строке, если у Вас есть свой %JAVA_HOME %/bin на Вашем ПУТИ.

1
ответ дан 1 December 2019 в 05:52
поделиться

Существует одна вещь, которую необходимо сделать с самого начала проекта, который будет огромной справкой: напишите читаемый код.

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

1
ответ дан 1 December 2019 в 05:52
поделиться

Я видел, что иногда просто предоставление JVM большей памяти "кучи" поможет вялому приложению. Этим управляют с -xmx и -xms опции JVM при запуске.

1
ответ дан 1 December 2019 в 05:52
поделиться

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

Некоторые сравнения

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

Просто запущение теста и затем изменение маленького бита кода или опции VM и выполнения его снова, могут привести к различным результатам, но не иметь никакого отношения к изменениям, которые Вы внесли.

3
ответ дан 1 December 2019 в 05:52
поделиться

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

Одна хорошая вещь ООП, то, что Вы смогли изменять реализации объекта, не изменяя интерфейс. Это позволяет Вам начать кодировать с naГЇve реализациями и заменять их в случае необходимости.

2
ответ дан 1 December 2019 в 05:52
поделиться

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

2
ответ дан 1 December 2019 в 05:52
поделиться

Используя StringBuilder вместо больших наборов Конкатенации строк дает большое относительное повышение производительности.

Однако я не могу постараться не говорить выгоду получающего работы общей практики, Профилирование. Я не знаю, Java, представляющий бесцеремонно (Только, использовал язык академически), но профилирование помогает Вам определить проблемные разделы своего кода, и намного легче зафиксировать определенные разделы, так как у Вас есть что-то для поиска.

5
ответ дан 1 December 2019 в 05:52
поделиться

Используйте последний VM - они - улучшение все время.

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

, Если это - приложение для GUI, Переключатель от Swing до AWT или возможно инструментария Eclipse, это, как предполагается, довольно быстро. Это более важно на более старом VMs (я работал встроенный некоторое время, и мы находимся на самом деле в 1.0.x vm, колебание даже не доступно)

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

можно также иметь в наличии объекты вместо того, чтобы освободить/перераспределить их. Существуют некоторые "ссылочные" классы, которые могут использоваться для содержания на объекты, в которых Вы не нуждаетесь, но могли бы хотеть снова использовать - GC не удалит их, если ему не будет нужно пространство.

Выделяют больше места в случае необходимости с - аргумент MX.

довольно трудно ускорить Java очень - HotSpot уже делает так много для Вас, что что-либо, что Вы делаете, что Вы думаете, могло бы убыстриться, Ваш код может часто замедлять его.

8
ответ дан 1 December 2019 в 05:52
поделиться

Не оптимизируйте вслепую. Используйте Yourkit или любого другого хорошего профилировщика для обнаружения "горячих точек" в приложении.

необходимо не только смотреть процессорное время, но также и в том, сколько памяти выделено и освобождено для определенного шага. Вы также хотите удостовериться, чтобы у Вас не было утечек памяти или потребления верхней памяти. Лучший инструмент для анализа потребления памяти, которое я знаю, является Памятью Eclipse Анализатор ( http://www.eclipse.org/mat ).

Другие размеры являются конкуренцией потока и проблемами IO. Для простого способа проанализировать состязательные проблемы, проверьте мой старый блог в https://www.sdn.sap.com/irj/sdn/weblogs? блог =/pub/wlg/4737

5
ответ дан 1 December 2019 в 05:52
поделиться

Для профилирования попробуйте JAMON в течение времени, контролируя и профилировщика NetBeans для общей производительности и контроля памяти.

2
ответ дан 1 December 2019 в 05:52
поделиться

Удостоверьтесь, что Ваш уровень журнала случайно не оставляют при ОТЛАДКЕ :)

12
ответ дан 1 December 2019 в 05:52
поделиться

"Измерьте, не угадывайте".
Вот польза статья об использовании Профилировщик NetBeans для ускорения библиотеки iText PDF. Я использовал Профилировщика NetBeans сам, и я нашел, что это, чтобы быть очень легким и полезным в разыскивании некоторой производительности выходит, я имел.

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

11
ответ дан 1 December 2019 в 05:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: