Новые функции JDK13 повышают эффективность разработки на один шаг.

JVM

С момента выхода JDK13 прошло уже почти 2 месяца, некоторые новые фичи уже были опробованы по частям, но в целом так и не разобрались. Думая о разработке на Java, я даже не знаю функций JDK (Java Developer Kit), которые я использую, что действительно неуместно.Если вы хотите стать более ценным разработчиком JAVA, вы должны быть в курсе последних функций JDK.

Тогда взгляните на этот запоздалый список новых функций JDK.

JDK13

Все функции JDK предлагаются и отслеживаются в процессе выполнения JEP:openjdk.java.net/jeps/0

Чтобы узнать, какие функции есть в каждой версии JDK, см. соответствующую домашнюю страницу JDK:откройте JDK.Java.net/projects/JD…

JDK13 в основном имеет 5 функций:

Dynamic CDS Archives

В JDK10 появились новые функции, но в то время этапы создания были громоздкими.

# JDK10中需要的步骤
1. 需要指定要归档那些类  -XX:DumpLoadedClassList=classes.lst
2. 创建归档   -Xshare:dump  -XX:SharedArchiveFile -XX:SharedClassListFile=classes.lst
3. 使用归档  -Xshare:on -XX:SharedArchiveFile

В JDK13 была введена новая опция для автоматического архивирования при выходе из программы:

java -XX:ArchiveClassesAtExit=app.jsa -cp app.jar HelloDemo

Используйте те же шаги архивирования, что и раньше,По умолчанию -Xshare:on включен

Процесс загрузки класса:

Загрузить->Проверить->Подготовить->Разобрать->Инициализировать->Использовать->Выгрузить

  • Загрузка: найдите местоположение класса, прочитайте содержимое файла класса из местоположения класса.
  • Проверка: проверка формата файла, проверка метаданных, проверка байт-кода и проверка ссылки на символ.
  • Подготовка: Этап формального выделения памяти для переменных класса и установки начального значения переменных класса, которые будут выделены в области методов. Хранятся как внутренние структуры данных JDK.
  • Синтаксический анализ: виртуальная машина преобразует символические ссылки в пуле констант в прямые ссылки, интерфейсы синтаксического анализа и синтаксический анализ полей.
  • Инициализировать: создать класс

Цель разработки CDS в основном состоит в том, чтобы повысить скорость при запуске приложения.Данные класса необходимо создать только один раз, а затем повторно использовать., что сокращает этапы загрузки, проверки и подготовки.Может быть фаза разбора

Ссылаться на:App CDS в действии

ZGC: Uncommit Unused Memory

ZGC был введен из JDK11, чтобы обеспечить более короткое время паузы во время GC, менее 10 мс, которое было добавлено в JDK13.Возврат незафиксированной, неиспользуемой памяти в операционную систему

ZGC состоит из множества ZPages.Zpages — это области памяти разного размера, которые делятся на малые, средние и большие. Когда ZGC сжимает память, Zpage выгружается в ZPageCache. ZpageCache — это область, которая готова к использованию в любое время. Если она используется, она будет немедленно удалена из ZpageCache в Zpage, но если Zpage в ZpageCache не использовалась для долгое время, то память освобождается и может быть возвращена в операционную систему позже.

When ZGC compacts the heap, ZPages are freed up and inserted into a page cache, the ZPageCache.

#设置一个时间多久从ZpageCache中移除(evict)Zpage
-XX:+UnlockExperimentalVMOptions -XX:+ZUncommit  -XX:ZUncommitDelay=<seconds> 

Ссылаться на:Полное руководство по ZGC

Reimplement the Legacy Socket API

Реализация Socket в нижней части JDK очень старая. Она используется с JDK1.0 до сих пор. Нижний уровень — это самый ранний код Java и C. Его очень сложно поддерживать и отлаживать для тех, кто разрабатывает JDK, поэтому он перереализован.Интерфейс Socket API.

  • До JDK13 используйте PlainSocketImpl

  • Представленный в JDK13, NioSocketImpl заменяет PlainSocketImpl.

Возьмем случай HelloWorld:

public class HelloApp {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8888)) {

            boolean running = true;
            System.out.println("listened 8888");
            while (running) {
                Socket clientSocket = serverSocket.accept();

                //do something with clientSocket
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

Но мы все еще можем переключиться на PlainSocketImpl. Необходимо настроитьjdk.net.usePlainSocketImpl

/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -XX:+TraceClassLoading  me/aihe/HelloApp.java | grep -i socketI

image-20191108074323662

/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -XX:+TraceClassLoading -Djdk.net.usePlainSocketImpl  me/aihe/HelloApp.java | grep -i socketI

image-20191108074413822

Switch Expressions (Preview)

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

Начальная запись переключателя:

int numLetters;
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        numLetters = 6;
        break;
    case TUESDAY:
        numLetters = 7;
        break;
    case THURSDAY:
    case SATURDAY:
        numLetters = 8;
        break;
    case WEDNESDAY:
        numLetters = 9;
        break;
    default:
        throw new IllegalStateException("Wat: " + day);
}

В JDK13 это можно записать так:

# 没有逻辑的返回
int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};

# 逻辑较多的处理
      String result = switch (number) {
            case 1, 2:
            		// 逻辑代码
                yield "one or two";
            case 3:
            	  // 逻辑代码
                yield "three";
            case 4, 5, 6:
                yield "four or five or six";
            default:
                yield "unknown";
        };
        return result;

Text Blocks (Preview)

При написании длинных строк в начале часто используется несколько строк для их конкатенации, одна из которых является пустой тратой производительности, но выглядит некрасиво. Особенно при написании строк HTML или операторов SQL.

// 比如HTML
String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, world</p>\n" +
              "    </body>\n" +
              "</html>\n";

Теперь это можно записать как:

String html = """
              <html>
                  <body>
                      <p>Hello, world</p>
                  </body>
              </html>
              """;

Уведомление:

  • Есть небольшая разница, нужно начинать с новой строки после """ в начале, и имеет ли """ в конце другой эффект
  • Обратите внимание, что при использовании может потребоваться обработка каждой строки.места с обеих сторон
"""
line 1
line 2
line 3
"""

=>

"line 1\nline 2\nline 3\n"
"""
line 1
line 2
line 3"""

=>

"line 1\nline 2\nline 3"

Наконец

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

Стоит попробовать!