Garbage Collection(GC)은 JVM(Java Virtual Machine)에서 동정으로 생성된 객체의 메모리를 자동으로 관리하는 메커니즘. GC는 애플리케이션의 메모리 누수를 방지하고, 더 이상 사용되지 않는 객체를 제거해 메모리를 효율적으로 사용하도록한다.
기본개념
1. GC의 역할
JVM이 힙 메모리(Heap Memory)에 생성된 객체 중 더 이상 사용되지 않는 객체를 식별하고 제거한다.
이를 통해 애플리케이션의 메모리 누수를 방지하고, 수동 메모리 관리의 필요성을 제거한다.
2. GC가 관리하는 영역
Heap Memory
Youg Generation (Eden, Survivor Space)
Old Generation (Tenured)
Metaspace
클래스 메타데이터를 저장하는 공간.
JVM Heap Memory 구조
1. Young Generation
새로 생성된 객체가 저장됨.
크기가 작고, 객체의 생존 시간이 짧은 경우가 대부분.
구성요소
Eden Space: 새로운 객체가 처음 생성되는 공간.
Survivor Space: Eden에서 살아남은 객체가 복사되는 공간.
2. Old Generation
Young Generation에서 오래 살아남은 객체가 이동.
크기가 크거나 생존 시간이 긴 객체가 저장됨.
3. Metaspace
클레스 로더와 메타데이터 정보를 저장.
GC 동작 과정
1. Minor GC
Young Generation에서 발생.
동작 원리
Eden에서 객체가 생성.
Eden이 가득차면 Minor GC가 실행
Eden에서 살아남은 객체가 Survivor Space로 이동.
여러번의 Minor Gc를 통해 Survivor Space에서 생존한 객체가 Old Generation으로 이동.
특징
실행 속도가 빠르며, Young Generation 크기에 다라 성능이 좌우됨.
Stop-The-World qkftod
2. Major GC(Full GC)
Old Generation에서 발생
동작 원리
Old Generation이 가득 차면 실행
사용되지 않는 객체를 제거하고 힙 메모리를 정리
특징
실행 시간이 길고 Stop-The-Wold가 발생
Minor GC보다 성능에 더 큰 영향을 미침.
3. GC의 실행 과정(가비지 식별, 처리 과정)
Mark: GC는 모든 객체를 순회하며 현재 참조되고 있는 객체를 식별하고 마크 함
Sweep: 마크되지 않은, 즉 참조되지 않는 객체를 메모리에서 제거함.
Compact(압축): 객체를 제거하고 남은 메모리 조각들을 모아 연속된 공간을 확보함. 힙메모리 단편화를 해소하는데 도움을 줌.
GC의 종류
JVM은 다양한 GC 알고리즘을 제공한다. 각각의 알고리즘은 GC성능과 애플리케이션 요구사항에 따라 다르다.
1. Serial GC
단일 스레드에서 작동
특징
작은 애플리케이션(싱글 스레드)에 적합.
Full GC중 애플리케이션이 멈추는 "Stop-The-Wold"시간이 길다.
2. Parallel Gc(Throughput GC)
여러 스레드를 사용해 GC를 수행
특징
처리량(Throughput) 지향.
적절한 애플리케이션 성능과 낮은 GC비용을 제공.
3.G1 GC
Java 9 이후의 기본 GC
특징
힙을 Region으로 나누어 관리.
Yong/Old Generation을 따로 구분하지 않고 필요에 따라 Region을 재배치.
data class Person(val name: String, val age: Int, val city: String)
val alice = Person("Alice", 30, "New York")
// 나이만 변경
val olderAlice = alice.copy(age = 31)
println(olderAlice) // Person(name=Alice, age=31, city=New York)
// 도시만 변경
val aliceInLondon = alice.copy(city = "London")
println(aliceInLondon) // Person(name=Alice, age=30, city=London)
// 여러 속성 변경
val bobInParis = alice.copy(name = "Bob", age = 25, city = "Paris")
println(bobInParis) // Person(name=Bob, age=25, city=Paris)
copy의 주의사항
copy():는 shallow copy를 수행한다. 중첩된 객체나 컬랙션은 참조만 복사된다.
복사를 너무 많이하면 성능에 악영향이 있을 수 있다.
변경되지 않은 값은 그대로 사용한다.
파라미터로 전달된 값만을 변경하고, 변경되지 않은 필드는 원본 객체 값을 그대로 사용한다.
이 방식으로 불필요한 객체 생성 작없을 회피한다.
data class User(val name: String, val age: Int)
val user1 = User("Alice", 25)
val user2 = user1.copy(age = 30)
println(user1.name === user2.name) // true, name 필드는 그대로 재사용
data class LargeData(val id: Int, val name: String, val description: String)
val large1 = LargeData(1, "Test", "This is a large data object.")
val large2 = large1.copy(description = "Updated description.")
println(large1.id === large2.id) // true, id 필드는 그대로 재사용
println(large1.name === large2.name) // true, name 필드도 그대로 재사용
println(large1.description === large2.description) // false, 변경된 description만 새로 생성
ApplicationContext 초기화 중에 CommandLineRunner와 ApplicationRunner 인터페이스를 구현한 빈들이 등록됨
이 빈들은 애플리캐이션 초기화가 완료된 후 추가 작업을 실행할 수 있음.
6.자동설정(Auto Configuration)
Spring Boot는 @EnableAutoConfiguration을 통해 여러 자동 설정 클래스(AutoConfiguration)을 활성화함.
자동 설정은 클래스 패스 및 환경 변수를 기반으로 애플리케이션에 필요한 빈을 자동으로 구성함.
Ex) DB Connection 설정, Web server 설정, Spring Security 설정 등
7.빈(Bean) 등록 및 DI(의존성 주입)
스프링 애플리캐이션 컨텍스트 내에서 모등 @Component, @Service. @Repository, @Controller 등의 빈을 스캔하여 등록
등록된 빈들 간의 의존성을 주입(생성자, 세터, 필드 기반)
프로파일 조건에 따라 특정 빈만 활성화될 수도 있음.
8.내장 웹서버 시작(Optional)
웹 어플리케이션인 경우, Spring Boot는 내장된 톰캣, 제티, 언더토우 등을 통해 HTTP서버를 시작
HTTP 포트, SSL설정 등이 적용됨.
서블릿 컨테이너가 초기화 되고 DispatcherSErvlet이 설정됨.
9.Spring MVC 또는 WebFlux 설정(웹 애플리케이션인경우)
DispatcherServlet을 통해 요청을 처리하는 기본 매핑을 설정
HandlerMapping,HandlerAdapter,ViewReolver등을 초기화 하여 웹 요청에 필요한 구성요소를 준비
10.이밴트 발행 및 리스너 실행
Spring Boot는 애플리케이션 실행 과정에서 여러 이벤트를 발행함.
ApplicationStartingEvent
ApplicationEnvironmentPreparedEvent
ApplicationPreparedEvent
ApplicationStartedEvent
ApplicationReadyEvent
위 이벤트를 통해 특정 시점에 사용자 정의 작업을 실행할 수 있음.
11.애플리케이션 준비 완료
애플리케이션 컨택스트 초기화가 완료되고, 모든 빈이 생성되고 초기화됨
CommandLineRunner 및 ApplicationRunner구현체가 실행됨.
ApplicationReadyEvent 가 발행되며 애플리케이션이 요청을 처리할 준비가 완료됨
12.애플리케이션 실행 상태 유지
Spring Boot는 실행 상태를 유지하며 HTTP요청을 대기하거나 비웹 애플리케이션에서는 작업을 지속함.
내부적으로 애플리케이션 컨택스트는 필요에 따라 라이프 사이클을 관리함.
13.애플리케이션 종료
애플리캐이션 종료시 Spring Boot는 ApplicationContext를 닫으며 빈의 destroy() 메서드 호출 및 리소스 정리를 수행
ApplicationFailedEvent 가 발행될 경우 애플리케이션 시패를 기록
Spring Boot Application으 LifeCycle에 대해 간략하게 정리 해 보았다. Spring 기반의 서비스를 운영 / 개발 하는 회사라면 자주 나오는 질문이니 숙지하고 있으면 좋다. 세부 내용까지는 힘들더라도 1~12번 넘버링 되어있는 순서만이라도 기억하면 좋다.
With the recently achievedstability of Kotlin Multiplatform, development teams worldwide can now seamlessly and confidently adopt it in production. However, this is just the beginning for KMP and its ecosystem. To equip you with the best cross-platform development experience, JetBrains aims to deliver a host of further improvements to the core Kotlin Multiplatform technology, Compose Multiplatform, KMP tooling, and KMP libraries in 2024. Read on to learn what we’re planning and our priorities in these areas.
최근 완성된 코틀린 멀티플랫폼의 안정성 덕분에, 세계의 많은 개발팀들은 이제 장애물 없이 코플린 멀티 플랫폼을 프로덕션에 자신있게 적용할 수 있게 되었다. 하지만 이는 단지 KMP(Kotlin Multiplatform)과 에코시스템을 시작하는것일 뿐이다. 최고의 크로스 플랫폼 개발을 경험을 갖추게 하기 위해서, 2024년에 JetBrains는 핵심 코틀린 펄티플랫폼기술, 컴포즈 멀티 플랫폼, KMP도구와 라이브러리 같은 미래의 발전을 주도할것이다. 이 분야에서 무엇을 배워야하고, 어떤 순서로 배뭐야할지 알아보자.
We’re dedicated to makingCompose Multiplatforma framework that allows creating beautiful and performant applications that look the same way on all supported platforms. Right now, our main focus is to getCompose for iOS to Beta, but we’re also working on other things. Here’s what we plan to do:
Make all Jetpack Compose core APIs and components multiplatform.
Improve rendering performance on iOS.
Make scrolling and text editing in Compose for iOS apps behave the same as in iOS native apps.
Implement a common API for sharing all types of resources.
Integrate with iOS and Desktop accessibility APIs.
Provide a solution for multiplatform navigation.
Many of the aforementioned improvements benefit Compose for Desktop, as well. In addition, we’re working on improving its stability and evolving it according to the feedback from those who use it in production.
We’ll also continue to explore what’s possible with Compose for Web, specifically with Wasm. Our nearest goal is to promote it to Alpha, which includes:
Allowing you to port your existing apps and reuse all of your common code.
Supporting different screen sizes, orientations, and densities.
Supporting input from a mouse, touchscreen, physical keyboard, or onscreen keyboard.
Improving performance and binary size.
우리는 컴포즈 멀티플랫폼을 만들기 위해 헌신했다. 컴포즈 멀티플랫폼은 우리가 지원하는 모든 플랫폼에서 어플리케이션이 동일하게 동작하고 동일하게 보이도록지원해주는 아름답고 효율적인 프레임워크이다. 지금 당장 우리가 집중하고 있는것은 iOS를 위한 컴포즈 Beta 버전이다. 하지만 우리는 다른것들도 진행하고있다. 아래는 우리의계획이다.
모든 Jetpack Compose 코어API와 멀티플랫폼 컴포넌트 제작
iOS에서의 랜더링 퍼포먼스 향상
iOS 앱용 컴포즈에서의 스크롤링, 문자 수정(text edting) 동작을 iOS네이티브 앱과 동일하게 만들기
모든 타입의 리소스를 공유할 수 있는 공통API 구현
iOS와 데스크탑의 접근성 API 통합
멀티플렛폼 네비게이션을 위한 소루션 제공
앞서 말한 많은 개선사항은 컴포즈 for 데스크탑에도 역시 도움이 된다. 더욱이, 우리는 제품 사용자들의 피드백을 통해서 안정성 향상과 새로운 기능 향상 작업도 진행하고있다.
우리는 또한 컴포즈 for Web, 특히 Wasm에 대한 작업도 지속하고있다. 우리의 가장 가까운 목표는 컴포트 for Web을 알파 버전으로 만드는 것이다. 알파버전엔 다음이 포함된다.
이미 존재하는 앱들의 포팅기능, 공통코드의 재사용 기능.
다양한 화면 사이즈(size, orientation, densitie) 지원,
마우스, 터치스크린, 키보드, 스크린 키보드 지원
퍼포먼스와 용량 향상.
Tooling
We’re committed to providing a great IDE experience for Kotlin Multiplatform. That means not only investing in the core platform and, for example, migrating Kotlin IDE plugin to K2 compiler frontend, but also providing a single tool (Fleet) for all Kotlin Multiplatform targets and codebases where you integrate it, eliminating the need to constantly switch between different IDEs.
We plan to quickly iterate over your feedback aboutusing Fleet for Kotlin Multiplatform development to make sure that we have everything you need for your development experience to be great. Among other things, we’re going to deliver in the following areas:
Enhanced support for Compose Multiplatform, including live preview for common code and visual debugging tools.
The IDE helping you with project configuration.
Unified and enhanced debugging experience for all parts of your Multiplatform project.
우리는 Kotlin Multiplatform을 위한 훌륭한 IDE 환경을 제공하기 위해 최선을 다하고 있습니다. 이는 Kotlin IDE plugin을 K2 compiler frontend 마이그레이팅 하는것 같은 코어 플랫폼 뿐만 아니라 개발자들이 통합하게 될 모든 Kotlin Multiplatform 타겟과 코드베이스를 위한 싱글툴(Fleet)을 제공하여 끊임없는 IDE변경을 제거한다는 의미입니다.
One of the popular Kotlin Multiplatform scenarios is sharing code with the iOS target. We want to focus on the development experience of iOS developers who work with Kotlin Multiplatform frameworks in their codebases.
The main initiative in this area is adirect Kotlin-to-Swift export. It will eliminate the Objective-C bottleneck, allowing for broader Swift language support and more natural exporting of APIs. Additionally, we are creating tools specifically for Kotlin library authors. These tools are designed to improve the compatibility and user-friendliness of Kotlin APIs when exported to Swift. We’re also paying close attention to tooling. The IDE and build systems are essential parts of the developer experience, and our goal is to ensure that the Swift Export integrates smoothly.
Our other initiatives include speeding up Kotlin/Native compilation, enhancing CocoaPods integration, and introducing support for exporting your framework with SwiftPM.
We also plan to continue exploring ways to improve the build setup of Kotlin Multiplatform applications. With Kotlin 1.9.20, we releasedhuge improvementsin the Gradle Multiplatform DSL, making it easier to read and write. We will continue to gradually improve it. In addition, we’re experimenting withAmper, a new project configuration tool focused on usability, onboarding, and IDE support.
Kotlin Multiplatform의 가장 유명한 시나리오 중 하나는 iOS 타겟괴 코드를 쉐어 하는 것 이다. 코드 베이스에서 코틀린 멀티플랫폼 프레임워크를 사용하는 iOS개발자의 경험에 중점을 두고 있다.
이 분야에서의 주요 계획은 Kotlin-to-Swift의 직접 번역(direct export)이다. 이를 통해 Object-C 보틀렉을 제거와 광범위한 Swift언어 지원, 자연스러운 API exporting이 가능해진다. 더욱이, 우리는 코틀린 라이브러리 개발자들을 위한 도구(tool)들을 만들었다. 이 도구들은 Swift로 export될 때 Kotlin API의 호환성과 사용자친화성을 개선하도록 디자인 되다. 우리는 툴링(tooling)에도 세심한 주의를 기울이고 있다. IDE와 빌드 시스템은 개발자 경험의 중요한 부분입니다. 우리의 목표는 Swift Export를 부드럽게 만드는 것 이다.
우리의 또 다른 우선순위는 Kotlin/Native 컴파일의 속도 증가, CocoaPods의 강화, SwiftPM을 사용한프레임워크 exporting 서포트 소개 를 포함하고 있다.
우리는 또한 코틀린 멀티 플랫폼 어플리케이션의 빌드 셋업 향상을 위한 방법도 지속적으로 탐험할 계획이다. Kotlin1.9.20애서 우리는 Gradle Multiplatform DSL의 거대한 향상을 릴리즈하여 읽고, 쓰기 쉽게 만들었다. 우리는 계속적으로 향상시킬 예정이다. 더욱이 우리는 Amper라는 실험을 하고있다. Amper는 사용성, 온보딩, IDE서포트에 초점을 맞춘 새로운 프로젝트 configuration tool이다.
As the Kotlin Multiplatform ecosystem is growing fast, the backward compatibility of the libraries becomes crucial. To ensure it, the JetBrains team and library creators must work together. Here’s our plan:
Improve the klib format so library creators can leverage their knowledge of building JVM libraries.
Implement the same code-inlining behavior in Kotlin Multiplatform libraries as for the JVM.
Provide a tool that ensures that your multiplatform library public API hasn’t changed in an incompatible way.
We’re also going to improve the publishing process for KMP libraries. Specifically, we plan to:
Make it possible to build and publish a KMP library without having a Mac machine.
Provide templates and extensive guidelines for creating and publishing a KMP library.
Even though Kotlin Multiplatform is now stable, we’re planning significant updates. But don’t worry: Libraries built with the current format will still work with newer Kotlin versions.
코틀린 멀티플랫폼의 에코시스템이 빠르게 성장함에 따라 라이브러리들의 이전 버전과의 호환성이 중요해졌다. 호환성을 위해서 JetBrains 팀과 라이브러리 제작자들은 함께 일해야만한다. 아래는 우리의 계획이다.
klib format 발전으로 라이브러리 크리에이터들이 그들의 JVM라이브러리 빌드 지식을 향상시킬 수 있다.
코틀린 멀티플랫폼의 code-inlining 행동이 JVM에서의 행동과 동일하도록 구현한다.
멀티플랫폼 라이브러리의 퍼블릭 API들이 호환되지 않는 방향으로 변경되지 않게 하는 도구를 제공한다.
우리는 또한 KMP라이브러리의 퍼플리싱 프로세스 향상할 것이다. 특히, 아래와 같은 계획이다.
문서화, 모든 개발자의 숙제이다. 필요한 이유는 알고있지만 하기 싫고 귀찮은 작업 중하나이다. 소프트웨어 개발 산출물 중 하나이기도 하고 다른 개발자 혹은 미래의 자신을 위해서 필요한 작업이기도하다.
필요성을 인지하고 있기때문에 모두 작성을 하려고하긴 하지만 어떻게 작성해야하는지를 잘 모른다. 책의 서두에도 나오는 '지식의 저주' 때문에 '이런것은 이미 알고있겠지' 혹은 '이렇게 자세히 쓰면 아무도 안읽을거야' 같은 생각을 하게된다.
사실 이책의 내용의 대부분은 이미 알고 있는 이야기였다. 그럼에도 이 책은 나에게 도움이 되었다. 왜냐면 "왜?"에 대한 답을 주기 때문이다. 문서화를 하다가 동료팀원에게 보완점을 이야기 했을때 "왜 그렇게 해야하죠?" 라는 말에 대답을 못하는 경우가 있다. 왜냐면 내 기준에선 당연한 이야기 이기 때문이다. 물론 '당연히 그렇게 해야죠'라는 말을 하면 싸움밖에 안날것이기때문에 당황하는 경우가 있었는데 이 책은 왜 그렇게 해야하는지에대해 알려주기 때문에 속이 시원해지는 경험을 했다.
이미 알고는 있지만 왜인지 몰랐던 문서에 대한 이야기들은 큰 도움이 되었다. 물론 내가 몰랐던 이야기들도 있었고, 문서화 방향에 대한 가이드이기 때문에 큰 도움이 되었다.
내용이 어렵지도 않고 술술 잘 읽히니 시간이 날때 카페에서 커피 한잔과 함께 가볍게 읽어보면 좋은 책이다.
AWS가 처음 나왔을때를 생각 해 본다. 온프레미스 서버의 연장선이다. 아니다, 이건 혁신이다. 이렇게 두가지로 이야기가 나뉘었던거같다. 훅자의 의견을 가진 개발자들은 앞다투어 AWS를 공부했고, 활용했다. AWS는 혁신이었다. 그들이 제공해주는 서비스는 개발에만 집중 할 수 있게 만들어 주었고, 버튼 몇번으로 인스턴스가 늘어나고, 프로토타이핑한 코드를 바로 운영서버에 적용시켜보고, 등등 여러가지 일을 할 수 있게 해줬다. 아이러니하게도 이런 AWS의 유용한 기능 덕분에 개발자는 AWS를 공부 할 필요가 없어지게 되었다. 너무 유용하고 다양한 기능을 제공해 주었고, 그 다양하고 유용한 기능들을 잘 활용하기 위해서는 전문가가 필요해졌기 때문이다. 개발자는 더이상 AWS를 공부 할 필요가 없어졌고, AWS는 DEVOPS 엔지니어, 인프라스트럭처 엔지니어같은 전문가들의 영역이 되었다.
그런데 정말 개발자는 더이상 AWS를 공부 할 필요가 없어졌을까? 아니다. 개발자는 AWS가 제공해주는 서비스를 어떻게 설정하는지, 정책을 어떻게 잡아야하는지 등의 세부사항은 알 필요가 없어졌지만 그래도 어떤기능을 제공하는지, 어떤 정책을 적용할 수 있는지 는 여전히 알고 있어야한다. 결국 시스템을 설계하고 운영하는것은 개발자의 일이기 때문이다. 내가 만들서비스의 특성에 따라 AWS가 제공해주는 기능을 효율적으로 사용하려면 결국 어떤 기능을 제공 해 주는지, 그 한계는 무엇인지 정도는 명확히 알고 있어야한다. 물론 설정은 전문가가 해주겠지만 말이다. 그런 점에서 업무에 바로 쓰는 AWS 입문은 개발자가 AWS를 공부할때 매우 적절한 도서이다. AWS가 제공 해 주는 기능들에 대한 설명도 충분히 들어있고, 직접 사용 해 보면서 장/단점에 대해서도 알려준다. 일단 이 책을 읽어보게된다면 AWS를 사용하는 시스템을 설계할 때 효율적이고, 수월하게 설계를 할 수 있을것이다.
국내에는 많은 AWS관련 서적이 나와있다. 대부분 내용은 대동소이하며 꼭 필요하고 중요한 내용으로 가득 차있다. 솔직한 말로 서점에서 AWS로 검색한 후 아무 책이나 보더라도 AWS를 공부하는 내용에서는 큰 차이가 없을것이다. 그럼에도 불구하고 '업무에 바로 쓰는 AWS입문'을 추천하는 이유가 있다. AWS는 매우 빠른 배포주기를 가지고 많은 업데이트가 일어나는 서비스이다. 때문에 이왕 공부하기 위해선 가급적 최근에 출판된 책을 이용하는것이 유리하다. 또한, 대부분 AWS책은 실습을 도와주기 위한 service UI 캡처 화면이 제공되는데 이 UI도 제법 자주 변경되기 때문에 실습을 따라하는 입장에서 최근에 출판된 도서가 훨씬 편하다.