2026. 6. 23. 20:41ㆍAI Product Building/SwiftBeam
2GB 파일도 가볍게
메모리 최적화의 비밀
메모리 폭발 없는 전송 엔진 설계
파일 전송 앱의 진정한 실력은 '대용량 파일'을 다룰 때 드러납니다. 수십 MB 수준의 사진은 어떻게든 보낼 수 있지만, 2GB가 넘는 고화질 영상이나 10GB 단위의 백업 파일을 보낼 때는 이야기가 달라집니다. 무턱대고 파일을 메모리에 올렸다가는 스마트폰이 비명을 지르며 앱을 강제 종료(OOM, Out Of Memory)해버리기 때문이죠. 이번 편에서는 SwiftBeam이 대용량 파일 앞에서도 평온함을 유지할 수 있는 비결, '스트림(Stream) 전송 기법'에 대해 깊이 있게 다뤄보겠습니다.
1. "전체를 다 읽지 마세요" - 메모리 스파이크의 공포
초보 개발자들이 가장 많이 하는 실수 중 하나가 file.readAsBytes()와 같은 메서드를 사용하여 파일 전체를 한꺼번에 메모리에 올리는 것입니다. 1GB 파일을 보내기 위해 1GB의 RAM을 점유한다면, 메모리가 넉넉하지 않은 보급형 스마트폰이나 멀티태스킹 중인 PC에서는 앱이 즉시 튕겨버립니다.
SwiftBeam은 이 문제를 해결하기 위해 '데이터 청크(Chunk)'라는 개념을 도입했습니다. 거대한 바위(파일)를 한꺼번에 옮기는 대신, 작은 조약돌(청크)로 쪼개어 하나씩 순차적으로 옮기는 방식입니다. 이렇게 하면 파일이 1GB든 100GB든, 앱이 사용하는 메모리는 항상 일정한 수준(예: 수십 MB)을 유지하게 됩니다.
2. 스트림(Stream): 멈추지 않는 데이터의 흐름
Dart 언어와 Flutter에는 Stream이라는 강력한 도구가 있습니다. 스트림은 말 그대로 '데이터의 흐름'입니다. 파일의 시작부터 끝까지 데이터를 조금씩 읽어오면서, 읽어온 즉시 네트워크 소켓(Socket)으로 쏘아 보내는 파이프라인을 구축할 수 있습니다.
SwiftBeam의 전송 로직은 다음과 같은 순환 구조를 가집니다.
① Read: 파일 시스템에서 64KB 만큼 데이터를 읽습니다.
② Process: 읽은 데이터를 즉시 암호화(AES-256)합니다.
③ Write: 암호화된 데이터를 네트워크 소켓 버퍼에 씁니다.
④ Repeat: 파일의 끝(EOF)에 도달할 때까지 이 과정을 반복합니다.
이 방식의 핵심은 '백프레셔(Backpressure)' 관리입니다. 네트워크 전송 속도가 파일 읽기 속도보다 느리다면, 무작정 데이터를 읽는 대신 잠시 기다렸다가 소켓이 비워지면 다시 읽기 시작합니다. 이를 통해 메모리 사용량을 완벽하게 통제할 수 있습니다.
3. 64KB의 미학: 버퍼 사이즈 최적화
"청크 사이즈를 얼마나 크게 잡아야 할까요?" 이는 성능과 안정성 사이의 줄타기입니다. 청크가 너무 작으면(예: 1KB) 시스템 콜이 잦아져 오버헤드가 발생하고 전송 속도가 느려집니다. 반대로 너무 크면(예: 10MB) 순간적인 메모리 사용량이 치솟아 불안정해질 수 있습니다.
SwiftBeam은 수많은 테스트 끝에 64KB라는 최적의 버퍼 사이즈를 찾아냈습니다. 이는 대부분의 OS 네트워크 버퍼 크기와 잘 맞물리며, 대용량 파일 전송 시에도 초당 수십~수백 MB의 속도를 내면서 메모리 사용량은 일정하게 유지하는 '골디락스(Goldilocks)' 포인트입니다.
4. 실시간 진행률과 속도 계산
스트림 전송의 또 다른 장점은 '실시간성'입니다. 데이터를 청크 단위로 보낼 때마다 현재까지 보낸 총 바이트 수를 추적할 수 있습니다. 이를 전체 파일 크기와 대조하면 0.1% 단위의 정밀한 진행률을 화면에 표시할 수 있죠.
또한, 최근 1초 동안 전송된 데이터 양을 계산하여 사용자에게 "현재 속도: 25MB/s"와 같은 유용한 정보를 실시간으로 제공합니다. 단순히 파일이 가고 있다는 정적인 표시보다, 숫자가 활발하게 움직이는 모습은 사용자에게 앱에 대한 강한 신뢰를 줍니다.
5. 안정성이 곧 기술력입니다
화려한 디자인보다 중요한 것은 '기본기'입니다. 파일 전송 앱에서 가장 중요한 기본기는 어떤 상황에서도 앱이 죽지 않고 끝까지 파일을 옮겨다 놓는 것입니다. SwiftBeam의 스트림 전송 엔진은 바로 그 안정성을 보장하는 핵심 심장부입니다.
하지만 전송 중에 와이파이가 끊기거나, 상대방이 잠시 방 밖으로 나간다면 어떻게 될까요? 처음부터 다시 보내야 할까요? 다음 편에서는 이 아까운 데이터 조각들을 지켜내는 기술, '일시정지와 이어받기(Resume) 로직'에 대해 알아보겠습니다.
다음 편 예고: [SwiftBeam #12] "멈추지 않는 전송" - 일시정지와 이어받기의 난제 해결
대용량 데이터를 다루는 Team M2Y의 기술력은 다른 서비스들에도 고스란히 담겨 있습니다.
안정적이고 최적화된 앱들을 아래 포트폴리오에서 확인해 보세요!
'AI Product Building > SwiftBeam' 카테고리의 다른 글
| [SwiftBeam #13] "여러 장의 사진도 한 번에" - 멀티 파일 전송을 위한 큐(Queue) 시스템 설계 (0) | 2026.06.25 |
|---|---|
| [SwiftBeam #12] "멈추지 않는 전송" - 일시정지와 이어받기의 난제 해결 (0) | 2026.06.24 |
| [SwiftBeam #09] "카메라만 대면 연결 끝" - QR 코드를 활용한 가장 직관적인 페어링 구현 (0) | 2026.06.21 |
| [SwiftBeam #08] "내 파일이 밖으로 새지 않게" - 로컬 네트워크 암호화 전송의 기초 (0) | 2026.06.20 |
| [SwiftBeam #07] "복잡한 IP 주소는 잊으세요" - 사용자 몰래 일어나는 포트 매칭과 연결 자동화 (0) | 2026.06.19 |