플러터란 무엇?
(본 글은 공부하며 적은 글로서 100% 맞음을 보장할 수 없습니다. 틀린 곳은 조언해주시면 감사하겠습니다!)
Dart Developers Korea 오픈채팅방 https://open.kakao.com/o/gYyufB6
Flutter가 요즘 핫하다
아래 그림을 보자
너무 핫하다 조만간 React-Native를 따라잡으려나?
많은 곳에서도 설명이 쓰여 있지만 Flutter는 iOS 및 Android 앱 개발, 웹 개발도 지원하고 미래의 구글의 새로운 운영체제 Fuchsia의 기본 개발 키트 인 새로운 크로스 플랫폼, 오픈 소스 UI 프레임 워크이다.
성능적인 면에서 React-Native보다 퍼포먼스가 좋을까? 사실 테스트를 해보지 않아서 모르겠지만 여러 다른 글들을 보니 Flutter가 좋다? 또는 좋을 것이다?라고 한다. 그 이유는 Flutter의 경우 React-Native처럼 중간에 Native View로 변환 과정이 없다. 그냥 Surface에 Skia 라이브러리를 이용하여 UI를 그려버린다. 물론 Back-End는 OpenGL ES , Vulkan을 사용하는 것 같다(Metal 도 쓰나? 글 쓰면서 함 봐봐야겠다).
여하튼 Flutter는 Dart 언어를 사용한다. Dart언어 만든 수장이 Flutter 수장이라고 하는데 필자도 카더라로 들은 것...
그렇다 보니 Flutter Engine에는 Dart VM도 함께 들어간다.
Dart로는 서버, 웹, 모바일(Flutter) 다 개발할 수 있다고 한다(https://www.dartlang.org/guides/platforms).
미리 말하지만 나의 글들은 의식의 흐름대로 이어나갈 것이다. 그런 적 있지 않은가?
아 이거 궁금하다. 여기선 또 이건 왜 그러지? 아그랫구나 에? 이건 또 뭐지? 타고 타고 넘어간다.
여기서도 그럴 것 같다. 주제랑 정말 부합되지 않아도 결론적으로 Flutter과 관련된 것이니 불필요하다고 느껴지면 과감하게 넘기자!
Dart를 잠깐 살펴볼까?
Dart의 컴파일 패턴은 Script, Script Snapshot, Application Snapshot, AOT로 나눌 수 있다.
Script는 일반적인 JIT모드이며 Script Snapshot은 앞의 Script와 차이점은 토큰화 된 코드로 묶는다. 이렇게 할 경우 컴파일 동안 lexer비용이 줄어들게 된다. Application Snapshot의 경우 앱용 JIT으로 보면 될 것이고 고, AOT는 AOT이다. JIT과 AOT에 대한 내용은 JVM에서도 많이 나온 내용이므로 생략하겠다.
Flutter의 컴파일 패턴은 어떨까?
Dart로 구성되니 Dart와 같아야 하지만 Android, iOS 개발의 큰 차이로 인해 좀 다른 점이 발생하였고 구성은 Script, Script Snapshot, Kernel Snapshot, Core JIT, AOT이다. 여기서 다 비슷하지만 다른 것만 설명하겠다. Kernel SnapShot의 경우 Dart 바이트코드 모드이고 이것은 사실 Flutter Project의 Core Snapshot이라고도 불린다. Cort JIT은 컴파일된 Dart 코드의 바이너리 형식의 일종으로서, 프로그램 데이터와 명령어가 특정 바이너리 형식으로 압축되고 실제로 Core JIT은 AOT 패턴의 일종이다.
(사실 나도 잘 모르겠다 쓰고는 있는데 어렵다)
개발단계의 컴파일 모드
플러터 앱 개발 시에는 UI 개발 가속화를 위해 "Hot Reload"를 제공하는데 이때 JIT 런타임보다 높은 성능을 요구하게 된다. 따라서 Flutter는 이 단계에서 Kernel Snapshot 모드를 사용하게 된다. 디버그 모드를 사용하다 보면 아래의 파일들을 만날 수 있다.
isolate_snapshot_data : 이 파일은 Dart Isolate 시작 속도를 높인다. 하지만 우리 코드랑은 노상관이다.
platform.dill : 이 파일은 Dart 런타임 커널이며, Flutter 엔진에만 관련된다.
vm_snapshot_data : 이 파일은 Dart VM 시작 속도를 높인다. 역시 우리 코드랑은 노상관이다.
kernel_blob.bin : 이것이 비즈니스 코드와 관련 있다.
릴리즈 단계의 컴파일 모드
실제 프로덕션에서는 응용프로그램을 더 빨리 실행해야 한다. 따라서 Flutter는 AOT를 선택하였고 이것은 플랫폼 특성별로 차이가 난다.
쓰다 보니 VM 이야기를 너무 많이 썼다....
쓰는 김에 하나만 더 쓰자
Dart의 스레드와 같은 개념을 Isolate라고 한다(https://api.dartlang.org/stable/2.1.0/dart-isolate/Isolate-class.html). 그리고 자체 관리 스레드를 생성하지 않고 Embeder가 책임진다. Embeder는 Flutter Engine에 있다. Isolate는 Isolated memory heap의 추상화이다. Isolate는 메모리를 공유하지 않는다. 본질적으로는 Self-contained Applicartion이다. Isolated 간 통신은 메시지 채널을 통해 통신한다.
사실 이 부분부터는 Flutter의 메모리 메커니즘이라고 볼 수도 있다.
다트 VM은 New Generation과 Old Generation으로 나뉜다.
아마 JVM의 Young Generation과 Old Generation과 비슷하지 않을까 싶다.
New Generation에서는 복사-클리어 알고리즘? 을 사용한다고 해야 하나... JVM과 비슷한 거 같다. GC발생 시 현재 사용된 메모리 블록의 남아있는 객체가 스페어 메모리 블록에 복사된 다음 현재 사용된 메모리 블록이 지워지고 마지막으로 두 메모리의 역할이 교체된다.
Old Generation은 New Generation에서 살아남은 객체들이고 CMS GC 알고라즘을 사용하여 메모리를 정리 한다. jvm 에서 gc를 생각하자. 잘 모르겠다면 이곳을 참고하자 -> https://d2.naver.com/helloworld/1329
메모리로 흘러온 김에
이미지 메모리도 보자
안드로이드의 경우 필자의 경험? 기억? 이 맞다면 Android 6.0, 7.0 때에는 ImageView사용 시 프로파일러로 보면 Java 메모리가 증가하지만 8.0은 Native 메모리가 증가한다.
Flutter Image Widget은?? 어느 메모리를 사용할까?? 궁금하지 않은가?
결과는 프로파일러를보면 Graphics 메모리를 사용한다!!
Graphics 메모리가 무엇이냐!
그러하다 Graphic Frame Buffer를 EGL Surface를 사용하는 것이다.
사실 이 글을 쓰게 된 것은 Flutter 엔진을 분석하다가 시작되었다.
추후에 왜 저렇게 되는지 작성하도록 하겠다.
여하튼! Flutter Image에서 사용되는 메모리는 Java메모리가 아니기 때문에 좀 해피하다고 할 수 있다.
일단 오늘은 여기서 끝내볼 까한다
다음 글에서 마저 Flutter 엔진의 4가지 스레드(https://brunch.co.kr/@myner/4)에 대해서 알아보도록 하자
<참고문헌>
https://github.com/flutter/flutter
https://github.com/flutter/engine
https://docs.flutter.io/index.html
https://www.yuque.com/xytech/flutter/kwoww1
https://www.jianshu.com/p/e6cd8584fdbb?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
https://proandroiddev.com/flutters-compilation-patterns-24e139d14177