SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 14 day free trial to unlock unlimited reading.
OpenJDK로 Java 언어 개선 주도권이 넘어간 후 Java의 개선 속도가 몰라보게 빨라지고 있습니다. Java를 언어, 런타임, 표준 API로 나눌 때 프로그래머에게 가장 중요하다고 볼 수 있는 언어 관점에서 Java가 앞으로 어떻게 개선될 지, Java의 미래를 알아보려고 합니다.
OpenJDK로 Java 언어 개선 주도권이 넘어간 후 Java의 개선 속도가 몰라보게 빨라지고 있습니다. Java를 언어, 런타임, 표준 API로 나눌 때 프로그래머에게 가장 중요하다고 볼 수 있는 언어 관점에서 Java가 앞으로 어떻게 개선될 지, Java의 미래를 알아보려고 합니다.
2.
자기 소개
* 우아한 형제들(배달의 민족) 인프라 서비스실 담당
* 한국스프링사용자모임(KSUG) 고문(이라 쓰고 홍보 담당이라 읽음)
* 페이스북 자바워키(Javawocky) 그룹 운영
https://www.facebook.com/groups/javawocky/
* 자바를 주로 사용하였었고 스칼라를 좋아만함
* 좋은 개발 문화와 개발 기법에 관심이 많음 (애자일, DevOps 관련)
* 연락처
페이스북: https://www.facebook.com/fupfin.geek
이메일: gyumee@gmail.com
4.
jAvA
Java = 언어 + VM + 라이브러리
자바백서: “The Java Language Environment”
언어 관점에서 OpenJDK의 진행중인 프로젝트 살펴 보기
5.
jAvA
Java, 개방형 혁신(Open Innovation)
업계
오픈 소스
커뮤니티
Java
6.
jAvA - 노동자의 언어
“해롭지 말자”
“Java presents a new viewpoint in the evolution of programming languages--
creation of a small and simple language that's still sufficiently comprehensive to
address a wide variety of software application development.”
Java is a blue collar language. It’s not PhD thesis material but a language for a
job. Java feels very familiar to many different programmers because we preferred
tried-and-tested things - James Gosling, “The Feel of Java"
설계목표 == 단순 & 친숙
8.
OpEnJDK::소개
# 설립
*2006/5, 썬이 자바원에서 자바를 오픈소스로 전환한다고 공표
*2006/11/13, JVM(HotSpot)과 컴파일러를 먼저 GPL 라이선스로 공개
*2007/5/8, 자바 클래스 라이브러리 GPL로 공개, 첫 OpenJDK 출시
*2007/6, 레드햇 아이스드티(IcedTea) 프로젝트 시작
*2007/11/5, 레드햇 OpenJDK 참여
*2011/7/28, OpenJDK에서 개발한 첫 자바 버전 OpenJDK 7 발표
*2014/3/18, OpenJDK 8 발표, JDK 8의 기반으로 쓰임
#정의
*오픈소스 자바 SE와 관련 프로젝트를 중심으로 한 커뮤니티
*JCP의 자바 규격 요청서(Java Specification Requests;JSR)와 별도로 JDK
개선 제안(JDK Enhancement-Proposal; JEP) 프로세스 운영
*JCP보다 훨씬 다양한 시도를 폭넓고 빠르게 시도
11.
OpEnJDK::개선흐름
# 언어의 현대화
* 표현 간소화 & 함수형 특성 도입
* 다중 코어 시대 대응
* System 자바
# 클라우드
* 시스템 통합;
* 성능 향상, 경량화;
* GC 개선, 관측성 개선
# 다언어용 범용 VM
* 강한 추상화와 시스템 통합을 양 방향으로 동시에 진행
* Macro-instructions (indy), simplified data model (value types)
* Java-on-Java (JSR 292 v2, Panama, Graal , Metropolis)
15.
AmbEr::소개
JEPs = {
JEP 286 지역변수 타입 추론,
JEP 301 열거형 개선,
JEP 302 람다식 잔반 처리,
JEP 305 패턴 매칭,
JEP 325 switch 식,
JEP 326 미가공_문자열
}
16.
AmbEr::지역변수_타입_추론(JEP-286)
# 지속적으로 확대된 타입 추론
* 자바 5: 제네릭 메서드 타입 추론
List<User> empty = Collections.<User>emptyList();
* 자바 7: 다이아몬드 연산자(<>)
List<User> users = new ArrayList<Users>();
* 자바 8: 람다식
users.stream.filter((User user) -> user.getSurName().equals(“park”)) ……
# 자바 10: 지역변수 타입 추론
var users = VisitorRegister.getVisitors();
17.
AmbEr::지역변수_타입_추론(JEP-286)
# 사용법
Collector<UserProfile, ?,
Map<Integer, Map<String, List<UserProfile>>>> groupingCollector =
Collectors.groupingBy(UserProfile::getAge,
Collectors.groupingBy(UserProfile::getCity));
var groupingCollector =
Collectors.groupingBy(UserProfile::getAge,
Collectors.groupingBy(UserProfile::getCity));
# 람다식(JEP 323)
BinaryOperator<Processor, String> op = (var x, var y) -> x.process(y);
BinaryOperator<Processor, String> op =
(@Nonnull var x, @Nullable var y) -> x.process(y)
18.
AmbEr::지역변수_타입_추론(JEP-286)
# 제약
// 필드와 메서드의 반환 타입
class MyClass {
var field = 0;
……
public var getAttribute() { …… };
}
// null 값 지정
var model;
model = “Gundam MkII”;
// 두 변수 이상 선언
var i = 0, j = 0;
// 중복 타입 추론
var dict = new HashMap<>();
20.
AmbEr::미가공_문자열(JEP-326)
JEPs = {
JEP 286 지역변수 타입 추론,
JEP 301 열거형 개선,
JEP 302 람다식 잔반 처리,
JEP 305 패턴 매칭,
JEP 325 switch 식,
JEP 326 미가공_문자열
}
21.
AmbEr::미가공_문자열(JEP-326)
//특수기호 후처리 없는 문자열
// 불필요한 후처리(escaping) 제거
out.println(“this".matches("wwww"));
out.println("this".matches(`wwww`));
// 자바 코드에 타 언어 소스나 틀을 맞춘 문서를 그대로 삽입
String script = "function hello() {n" +
" print('"Hello World"');n" +
"}n" +
"n" +
"hello();n";
String script = `
function hello() {
print('"Hello World"');
}
hello();
`
22.
AmbEr::미가공_문자열(JEP-326)
# 특징
- 짝맞춤을 통해 미처리 문자열 내 “`” 문자 허용,
- 개행문자를 제외한 모든 문자를 처리 없이 그대로 사용,
- 후처리를 위한 String 클래스에 escape() 메서드 추가,
- 아직 JEP 처리 상태는 Candidate라 향후 변경 가능성이 큼
# 다양한 사용 예
`"` // a string containing " alone
``can`t`` // a string containing 'c', 'a', 'n', '`' and 't'
`This is a string` // a string containing 16 characters
`n` // a string containing '' and 'n'
`u2022` // a string containing '', 'u', '2', '0', '2' and '2'
`This is a
two-line string` // a single string constant
23.
AmbEr::Switch식(JEP-325)
JEPs = {
JEP 286 지역변수 타입 추론,
JEP 301 열거형 개선,
JEP 302 람다식 잔반 처리,
JEP 305 패턴 매칭,
JEP 325 switch 식,
JEP 326 미가공_문자열
}
24.
AmbEr::Switch식(JEP-325)
# Switch 문? Switch 식?
* 식 == 연산 후 값 반환
* if 문
if(조건식) { … } else { … }
var result = if(조건식) { … } else { … } //(x)
* 삼항연산자를 사용한 식
var result = 조건식 ? 값1 : 값2; //(0)
* 지금까지 자바에서 swtich는 문이었으나 식으로도 사용 가능
25.
AmbEr::Switch식(JEP-325)
//switch 문
int numDays = 0;
switch (month) {
case 1: case 3: case 5:
case 7: case 8: case 10:
case 12:
numDays = 31;
break;
case 4: case 6:
case 9: case 11:
numDays = 30;
break;
case 2:
if (((year % 4 == 0) &&
!(year % 100 == 0))
|| (year % 400 == 0))
numDays = 29;
else
numDays = 28;
break;
}
//switch 식
int numDays = switch (month) {
case 1, 3, 5, 7, 8, 10, 12 -> 31;
case 4, 6, 9, 11 -> 30
case 2 ->
(((year % 4 == 0) &&
!(year % 100 == 0))
|| (year % 400 == 0)) ?
29 : 28;
}
간략해진 코드
26.
AmbEr::패턴 매칭
JEPs = {
JEP 286 지역변수 타입 추론,
JEP 301 열거형 개선,
JEP 302 람다식 잔반 처리,
JEP 305 패턴 매칭,
JEP 325 switch 식,
JEP 326 미가공_문자열
}
27.
AmbEr::패턴 매칭::데이터_클래스
# 자바 객체의 다양한 용도
* “구조체”, // C, 파스칼
* “값”, // Integer, Long, Boolean, Double
* “데이터 전달 객체(DTO)”,
* “객체”, // OOP의 최소 단위, 데이터보다는 행위 기준
* “컴포넌트”
# 구조체/데이터 전달 객체로서의 일반적인 자바 객체
public class Coordinate {
private double lat;
private double lon;
public Coordinate(double lat, double lon) {
this.lat = lat;
this.lon = lon;
}
// Getters/Setters, toString(), equals(), hashCode(), etc. 필요
}
28.
AmbEr::패턴 매칭::데이터_클래스
대수적 자료형(algebraic data types)
//스칼라 케이스 클래스
case class Coordinate (lat: Double, lon : Double)
//코틀린 데이터 클래스
data class Coordinate(val lat: Double, val lon: Double)
//자바 데이터 클래스 (안)
record Coordinate(double lat, double lon) {}
//사용 예: 산술식
interface Exp { }
abstract record BinOpExp(Exp left, Exp right) implements Exp {};
abstract record UnOpExp(Exp exp) implements Exp {};
record PlusExp(Exp left, Exp right) extends BinOpExp(left, right) {};
record SubExp(Exp left, Exp right) extends BinOpExp(left, right) {};
record MulExp(Exp left, Exp right) extends BinOpExp(left, right) {};
record DivExp(Exp left, Exp right) extends BinOpExp(left, right) {};
record NegExp(int constant) implements Exp {};
record IntExp(int constant) implements Exp {};
29.
AmbEr::패턴매칭
# 패턴매칭 == Switch식 + 타입 비교
interface Shape {};
record Point(int x, int y) implements Shape;
record Circle(Point center, int radius) implements Shape;
……
Canvas newCanvas;
// 기존 if를 사용한 타입 확인 방식
if(shape instanceOf Point) {
Point pt = (Point) shape;
newCanvas = canvas.drawPoint(pt.x, pt.y);
}
else if (shape instanceOf Circle) {
Circle cir = (Circle) shape;
newCanvas = canvas.drawCircle(cir.center.x, cir.center.y, cir.radius);
}
else if (shape instanceOf Rectangle) {
……
}
else if (shape ……
30.
AmbEr::패턴매칭
# 패턴매칭 == Switch식 + 타입 비교
// Switch 식을 이용한 타입 확인 방식
Canvas newCanvas =
switch(shape) {
case Point pt -> canvas.drawPoint(pt.x, pt.y);
case Circle cir -> canvas.drawCircle(cir.center.x, cir.center.y,
cir.radius);
case Rectangle rct -> ……
……
default -> canvas;
}
31.
AmbEr::패턴매칭
# 패턴매칭 == Switch식 + 타입 비교 + 객체 분해
객체를 분해해서 생성자 인자값을 다시 꺼내서 변수에 할당
interface Exp { }
abstract record BinOpExp(Exp left, Exp right) implements Exp;
record PlusExp(Exp left, Exp right) extends BinOpExp(left, right);
record SubExp(Exp left, Exp right) extends BinOpExp(left, right);
record IntExp(int constant) implements Exp;
……
int eval(Exp e) {
return switch(e) {
case IntExp(var i) -> i;
case PlusExp(var l, var r) -> eval(l) + eval(r);
case SubExp(var l, var r) -> eval(l) - eval(r);
……
}
32.
AmbEr::패턴매칭
# 비지터 패턴이었다면...
interface Exp { accept(ExpVisitor visitor); }
record IntExp(int constant) implements Exp { … }
record PlusExp(Exp left, Exp right) implements Exp {
public int accept(ExpVisitor visitor) { return visit(this); }
}
record SubExp(Exp left, Exp right) implements Exp { … }
……
class ExpVisitor {
public int visit(IntExp e) {
return e.constant;
}
public int visit(PlusExp e) {
return e.left.accept(this) + e.right.accept(this);
}
public int visit(SubExp e) { … }
……
}
33.
AmbEr::패턴매칭
# 패턴매칭 == Switch식 + 타입 비교 + 객체 분해 + 값 비교
객체를 분해해 얻는 생성자 인자값과 패턴에 주어진 값을 비교
#유클리드 호제법 예제
2개의 자연수(또는 정식) a, b에 대해서 a를 b로 나눈 나머지를 r이라 하면(단, a>b), a와 b의
최대공약수는 b와 r의 최대공약수와 같다.
gcd(a, 0) = a
gcd(a, b) = gcd(b, a mod b)
int gcd(Pair pair) {
return switch(pair) {
case Pair(var a, 0) -> a;
case Pair(var a, var b) -> gcd(Pair.of(b, a % b));
}
34.
AmbEr::패턴매칭
# 패턴매칭 == Switch식 + 타입 비교 + 객체 분해 + 값 비교
패턴을 중첩해서 적용할 수 있음
Exp simplify(Exp exp) {
return switch(exp) {
case IntExp -> exp;
case NegExp(var e) -> new NegExp(simplify(e));
case NegExp(NegExp(var e)) -> simplify(e);
case PlusExp(IntExp(0), var e),
PlusExp(var e, IntExp(0)),
SubExp(IntExp(0), var e),
SubExp(var e, IntExp(0)) -> simplify(e);
case PlusExp(var l, var r) -> new PlusExp(simplify(l), simplify(r));
case SubExp(var l, IntExp(0)) -> simplify(l);
case SubExp(var l, var r) -> new SubExp(simplify(l), simplify(r));
};
}
36.
vAhAllA::소개
JEPs = {
JEP 169: 값 객체
JEP 218: 원시타입 제네릭(제네릭 특화)
JEP 193: 변수 핸들
}
자바 제네릭의 한계를 극복하고 참조 타입 때문에 발생하는 자바 성능을 개선
37.
vAhAllA::기존자바타입
자바의 타입 = {원시 타입, 참조 타입}
원시 타입 = {boolean, byte, char, short, int, long, float, double}
참조 타입 = {모든 객체, 배열}
* 비효율적인 참조 타입에 의존
* 힙 메모리 정리(GC)가 복잡해짐
* 원시 타입을 대응하는 객체로 변환(boxing)/복원(unboxing)하는 비용 발생
변수
데이터
데이터
변수
변수
참조
참조
참조
38.
vAhAllA::값타입
Rational[] rationals = …
객체 참조
객체 참조
객체 참조
분모
분자
분모
분자
분모
분자
배열
객체
객체
객체
분모
분자
분모
분자
분모
분자
배열
39.
vAhAllA::값타입
“코드는 클래스 같지만 동작은 값처럼”
* 데이터의 일렬, 밀집 배열
* 원시타입과 참조타입의 간극 채움
* 기존 참조타입(L-타입)에 새로운 값 타입(Q-타입)을 JVM에 추가
문법
value class Rational {
final int numer; // 분자
final int denom; // 분모
}
* 작은 구조체에 적합: 복소수, 좌표, 도형, 튜플
* 불변(Immutable)
* 동시성 환경에 유리
* GC에 유리
* 자바 원시 타입 외 시스템 고유의 자료 타입 표현 가능(ex, int128)
40.
vAhAllA::자바_제네릭
#참조 타입만 허용하는 자바 제네릭
List<int> primeNums = new ArrayList<>(); // compile error
#타입 소거
* 자바 제네릭은 컴파일러 기술
* 타입 매개변수 값은 소거되어 VM은 정보를 알지 못함 (하위호환성)
ArrayList<String>();
ArrayList<Integer>();
ArrayList<User>();
ArrayList<Point>();
ArrayList.class
ArrayList.class
ArrayList.class
ArrayList.class
소스코드 JVM
컴파일
41.
vAhAllA::제네릭_특화
# 값타입에 맞게 동적으로 클래스 변조
ArrayList<int>();
ArrayList<Rational>();
ArrayList<Complex>();
ArrayList${T=int}.class
ArrayList${T=Rational}.class
ArrayList${T=Complex}.class
소스코드 JVM
컴파일
# C++ 템플릿 비교
* C++ 템플릿은 제네릭 특화처럼 매 적용마다 별도 코드를 생성
* 자바 제네릭 특화는 런타임에 동작, C++ 컴파일 시점에 동작
* 자바 제네릭은 타입 매개변수에만 적용
* 참조 타입에는 기존처럼 타입 소거 적용
# 포인터 다형성 vs 표상(representation) 다형성
42.
vAhAllA::값_기반_클래스
# 값 기반 클래스(Value Based Class)
* 자바 8에 도입된 클래스 규격
*final이고 값이 변해서는 안됨
*값 변경 가능 객체를 참조할 수는 있음
*equals, hashCode, toString은 상태로만 계산해야 하며 식별자를 써서는 안됨
*equals()로만 동치성을 비교해야 하며 동일성(==)은 보장 안함
*팩토리 메서드를 사용해서만 객체를 생성해야 함
*동치인 두 객체에는 행동이 언제나 동일해야 함
*식별자 기반 작업은 예측할 수 없는 결과 발생 가능 (동기화, 직렬화 등)
//java.util
Optional, OptionalDouble, OptionalLong, OptionalInt
//java.time
Duration, Instant, LocalDate, LocalDateTime, LocalTime, MonthDay, OffsetDateTime, OffsetTime,
Period, Year, YearMonth, ZonedDateTime, ZoneId, ZoneOffset
//java.time.chrono
HijrahDate, JapaneseDate, MinguaDate, ThaiBuddhistDate
43.
vAhAllA::최소_값_타입(Minimal Value Type)
# 최소 값 타입
* 발할라(Vahalla) 프로젝트의 첫 가시적 결과, 부분 집합
* indy와 같이 “VM 먼저, 언어는 나중” 접근 방식(언어와 VM의 분리)
* 자바 문법 변화 없음
* 값 가능 클래스: @jdk.incubator.mvt.ValueCapableClass
* JVM 내부적으로만 값 타입 동작 (선택가능)
* 값 기반 클래스를 JVM의 1등급 구성체로 취급
* java -Xverify:none -XX:+EnableMVT <Test>
44.
vAhAllA::VCC_&_DVC
# 값 가능 클래스
* 클래스는 final로 상속 불가
* 인터페이스가 아닌 일반 클래스
* Object를 직접 상속해야 함
* 멤버 필드는 모두 final로 변경 불가
* equals, hashCode, toString을 재정의(Override)
* clone과 finalize는 재정의하지 말아야 함
#파생 값 타입
* 값 타입으로 표시됨
* 값 가능 클래스에서 유도된 새 이름이 주어짐
* VCC의 상속 타입은 제거됨
* VCC의 모든 메서드와 생성자는 제거됨
* 멤버필드는 변경 없이 유지
VCC소스코드
VCC클래스파일
DVC메모리의 클래스 VCC메모리의 클래스
컴파일
클래스로더
VCC 값 가능 클래스
DVC 파생 값 클래스
45.
vAhAllA::최소_값_타입_성능
# valuetypifier
* 자바 8 코드를 값 타입 관련 opcode로 변경하는 도구
* https://github.com/forax/valuetypify
// 코드
ColorList list = new ColorList();
for(int i = 0; i < 1_000_000; i++) {
list.add(new Color(i, i, i));
}
// 결과 (참조 타입)
Color(2.2517998E7, 2.2517998E7, 2.2517998E7)
creation time 2886.933223 ms
average time 606.217409 ms
// 결과 (값 타입)
Color(2.2517998E7, 2.2517998E7, 2.2517998E7)
creation time 1039.692931 ms
average time 70.152561 ms
47.
lOOm::화이버
#컨티뉴에이션(Continuation; 지속, 연속)
* 작업 단위
* 중단 후 재실행 가능
# 화이버(Fiber)
* 자바가 관리하는 경량 쓰레드 (쓰레드는 OS가 관리)
* 쓰레드처럼 동작하지만 쓰레드보다 훨씬 가볍게 동작
* 컨티뉴에이션을 관리
* 서버는 대부분 시간을 IO 응답을 기다리지만 쓰레드는 너무 무거움
* 쓰레드를 추상화해 사용하는 비동기 모델은 복잡함 (액터, 반응형 프로그래
밍 등)
* 동기 방식과 유사하게 확장 가능한 프로그래밍 작성 가능
* 기존 코드를 훨씬 가볍게 돌릴 수 있는 파이버가 필요