Java 14
JEP 361: Switch Expressions
- Java 12-13 에서 preview feature 였음. Java 14 에서 standard 로 변경
String result = switch (day) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if(day.isEmpty())
yield "Please insert a valid day.";
else
yield "Looks like a Sunday.";
}
};
JEP 305: instanceof 패턴 매칭
- preview feature
- if (obj instanceof SomeType) 후 if 블럭에서 (SomeType) obj 캐스팅 불필요:
before:
if (obj instanceof SomeType) {
SomeType someType = (SomeType) obj;
someType.doSomething();
}
after:
if (obj instanceof SomeType) {
obj.doSomething();
}
JEP 358: NullPointerException 메시지 개선
- 정확히 어디서 null 참조가 발생했는지 알기 쉽게 표시.
- 메서드 체이닝 코드 디버깅에 있어 특히 편해질 것으로 보임.
before:
String name = someInstance.getValue().toString();
//Stacktrace
Exception in thread "main" java.lang.NullPointerException
at NullPointerExample.main(NullPointerExample.java:5)
after:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "SomeValue.toString()" because the return value of "something.getValue()" is null
at NullPointerExample.main(NullPointerExample.java:4)
JEP 359: Records
- preview feature
- 순수 데이터만 담는 클래스.
- 키워드 class 대신 record 를 사용하며, 아래와 같이 선언함:
record Car(String name, String manufacturer) {}
- 컴파일 시 final 클래스가 되며, java.lang.Record 를 상속. (enum 과 유사.)
- 함께 선언한 필드는 모두 final이 되며, 값을 대입하는 public 생성자가 자동으로 생성됨:
public Car(String name, String manufacturer) {
this.name = name;
this.manufacturer = manufacturer;
}
- 필드의 getter 메서드도 자동으로 생성됨.
- toString, hashcode, equals 로 자동으로 오버라이딩하며, 필드 값을 기준으로 같은 결과를 반환.
- 생성자에 사용된 필드 외에 다른 인스턴스 필드를 선언할 수 없음.
- 인스턴스 메서드 선언 가능.
- interface 구현 가능.
- static 필드, 메서드는 선언 가능.
- 생성자 오버로딩 가능.
- 자동 생성된 기본 생성자 변경 가능. 이 때 생성자 파라미터 생략 가능:
record Car(String name, String manufacturer) {
public Car { // 파라미터 생략 가능. name, manufacturer 이 숨겨져 있다.
// 파라미터 할당문 생략 가능. 컴파일러가 자동 생성.
}
}
- java.lang.Class 에 isRecord, getRecordComponents 가 추가됨. isRecord는 이 클래스가 record 타입인지 확인하고, getRecordComponents는 record 필드를 가져옴.
JEP 368: Text Blocks
- preview feature (second preview)
- Java 13 에서 등장한 Text Blocks 에 새로운 이스케이프 2 개 추가
- \ (백슬래시) : 자동 줄바꿈을 방지함:
String inline = """
1\
2\
3\
""";
System.out.println(inline); // "123"
- \s: 공백을 유지함. Text Blocks 에서는 문자열이 자동으로 stripped되기 때문에, 기본적으로 앞뒤 공백이 제거됨. 공백을 유지하고 싶은 경우 사용.
JEP 343: Packing Tool (jpackage)
- incubator
- 자바 어플리케이션 패키징을 손쉽게 하기 위해 사용.
- 플랫폼에 맞는 패키징을 돕는다. (Linux: deb, rpm / macOS: pkg, dmg / Windows: msi, exe)
JEP 345: NUMA-Aware Memory Allocation for G1
- Non-Uniform Memory Access (NUMA) 는 멀티프로세싱 시스템에서의 멀티프로세서 클러스터링 아키텍처로, 각 프로세스가 독립적인 로컬 메모리를 보유하도록 하여 성능 향상을 도모한다. 프로세서와 그 프로세서의 메모리(로컬 메모리) 로 하나의 NUMA node를 구성하며, 프로세서가 자신의 node의 메모리에 빠르게 접근할 수 있다. 외부 node로의 접근은 상대적으로 느리며, 그 속도는 node의 거리가 멀수록 더 느리다.
- Java 14 에서는 G1이 NUMA를 인식하여 새로 메모리를 할당할 때 현재 쓰레드가 위치한 같은 NUMA node에 가용 공간이 있는지를 먼저 찾고, 없으면 가장 인접한 node를 검색하는 방식으로 NUMA 아키텍처의 성능 이점을 활용하도록 한다.
- 다음 파라미터로 활성화함:
+XX:+UseNUMA
- 위 파라미터를 지정하면 JVM이 초기화될 때 전체 NUMA nodes에 regions를 분포하도록 한다.
JEP 349: JFR Event Streaming
- JFR 이벤트를 수신할 수 있는 API 를 제공.
- in-process, out-of-process 어플리케이션 모두에 사용 가능.
- jdk.jfr.consumer 패키지 사용.
- CPU 사용률과 모니터 락 경합 이벤트를 10ms 주기로 수신하는 예시 코드:
try (var rs = new RecordingStream()) {
rs.enable("jdk.CPULoad").withPeriod(Duration.ofSeconds(1));
rs.enable("jdk.JavaMonitorEnter").withThreshold(Duration.ofMillis(10));
rs.onEvent("jdk.CPULoad", event -> {
System.out.println(event.getFloat("machineTotal"));
});
rs.onEvent("jdk.JavaMonitorEnter", event -> {
System.out.println(event.getClass("monitorClass"));
});
rs.start();
}
JEP 352: Non-Volatile Mapped Byte Buffers
- java.nio.MappedByteBuffer 가 non-volatile memory (NVM) 의 파일을 로드 처리할 수 있도록 함.
JEP 364: ZGC on macOS
- experimental
- macOS에서 ZGC 지원.
- macOS에서 메모리 멀티 매핑 지원.
- 인접하지 않은 메모리 reservations 지원.
JEP 365: ZGC on Windows
- experimental
- Windows에서 ZGC 지원.
- Windows 10 지원.
- WIndows Server version < 1803 미지원.
JEP 370: Foreign-Memory Access API
- incubator
- 새로운 native memory 접근 API 추가.
- 자바 어플리케이션의 힙 메모리 사용은 메모리 효율성, (상대적으로)낮은 성능, GC 등의 이슈가 있음.
- 이에 때에 따라서 외부 메모리(native memory)에 접근할 필요가 있는데, 기존 접근 방법은 ByteBuffer API, Unsafe API 두 가지가 있음.
- ByteBuffer API는 native memory 할당을 가능하게 하지만, 가용 메모리가 최대 2 기가라는 점과, 메모리 해제를 GC가 책임져야 한다는 한계가 있음. 때문에 잘못된 방법으로 API를 사용하면 메모리 릭이 발생할 수 있고 OOM으로 연결됨.
- Unsafe API는 메모리 관리에 굉장히 효율적일 수 있지만, 잘못 사용하면 JVM 크래시를 일으킬 수 있고, 표준 API가 아니라는 단점이 있음.
- Java 14 는 native memory 접근을 위한 세 가지 추상화를 제공: MemorySegment, MemoryAddress, MemoryLayout.
- MemorySegment: 힙 또는 native memory에 연속된 메모리 공간을 할당함. 다음과 같이 사용할 수 있음:
MemorySegment memorySegment = MemorySegment.allocateNative(200); // 200 바이트의 native memory 할당.
MemorySegment memorySegment = MemorySegment.ofArray(new long[100]); // 자바 힙 메모리 segment.
MemorySegment memorySegment = MemorySegment.ofByteBuffer(ByteBuffer.allocateDirect(200)); // buffer memory segment.
mapped memory file에도 사용할 수 있음. (mapped memory segment):
MemorySegment memorySegment =
MemorySegment.mapFromPath(Path.of("/tmp/memory.txt"), 200, FileChannel.MapMode.READ_WRITE);
memory segment는 현재 쓰레드에 묶임. 다른 쓰레드에 있는 memory segment에 접근하려면 acquire 메서드를 통해 접근 권한을 획득해야 함.
memory segment는 JVM 안정성을 위해 그 접근에 있어 두 가지 바운더리가 있음:
Spatial boundary: 공간적 경계. 접근 가능한 범위가 정해져 있어, 이 범위 밖의 메모리에 접근 시도하면 exception 발생.
Temporal boundary: 시간적 경계. 생성 및 사용되고, 더 이상 사용되지 않으면 closed된다. closed된 영역에 접근 시도하면 exception 발생.
- MemoryAddress: memory segment의 memory offset. 메모리의 데이터를 검색하거나 할 때 사용됨:
MemoryAddress address = MemorySegment.allocateNative(100).baseAddress();
- MemoryLayout: memory segment의 내용을 제공. 특히 메모리를 점유하는 요소의 사이즈를 제공하여 메모리가 요소에 어떤식으로 분산할지 정의할 수 있음.
int numberOfPoints = 10;
MemoryLayout pointLayout = MemoryLayout.ofStruct(
MemoryLayout.ofValueBits(32, ByteOrder.BIG_ENDIAN).withName("x"),
MemoryLayout.ofValueBits(32, ByteOrder.BIG_ENDIAN).withName("y")
);
SequenceLayout pointsLayout =
MemoryLayout.ofSequence(numberOfPoints, pointLayout);
- MemoryHandles: MemorySegment로 할당한 메모리를 사용함:
long value = 10;
MemoryAddress memoryAddress = MemorySegment.allocateNative(8).baseAddress();
VarHandle varHandle = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder());
varHandle.set(memoryAddress, value);
assertThat(varHandle.get(memoryAddress), is(value));
- 이 외에 다양한 MemoryLayouts가 존재함: ValueLayout, SequenceLayout, GroupLayout.
출처:
https://www.journaldev.com/37273/java-14-features
https://dzone.com/articles/a-first-look-at-records-in-java-14
'Java > Core' 카테고리의 다른 글
Java 13 간략히 정리 (0) | 2020.07.16 |
---|---|
Java 12 간략히 정리 (0) | 2020.07.15 |
Java 11 간략히 정리 (0) | 2020.07.15 |
Java 10 간략히 정리 (0) | 2020.07.15 |
IO, NIO, NIO2 (0) | 2020.02.26 |