메모리 관리는 모든 플랫폼 개발자가 느끼는 가장 큰 고민거리 일 것입니다. 특히, 웹 상에서 실행하는 애플리케이션은 메모리 설계를 잘못할 경우, 브라우저가 다운되거나, 시스템의 메모리를 독점해서 시스템에 중대한 위협을 끼칠 수 있죠.
하지만, 웹 플래시 애플리케이션 개발자들은 메모리를 직접 관리할 방법은 마땅히 없습니다. 단지, 현재 비 활성화된 객체를 잘 관리해 주는 것이 중요합니다. 특히, Flex의 일부 컴포넌트들은 이러한 메모리 관리에 염두를 두지 않고 설계 된 것이 많아, 개발자들을 골치아프게 하고 있습니다. ^^;;
그리고 재작년 AIR가 아폴로라는 코드네임으로 처음 발표 되었을때에도, 보안전문가들은 현 플래시의 메모리관리 방식을 지적하며, AIR 애플리케이션이 과다한 메모리를 점유하여 사용자의 보안에 중대한 위협을 줄 수 있다고 수 차례 경고하였습니다.
어도비에서는 이러한 보안 전문가들의 권고를 적절히 수렴하여, 디버그용 Flash Player와, AIR 애플리케이션에서 직접적인 메모리 관리가 가능하도록, 가비지컬렉션 기능을 새롭게 도입하였습니다.
아울러 최근 릴리즈 된, AIR 1.5.2 에서도 XML 객체에서 새로운 메모리 관리 방식을 도입하였습니다.
이 글에서는, AIR의 메모리 관리 방식에 대해 살펴보겠습니다.
가비지 컬렉션
우선 가비지 컬렉션이 무슨 용어인지에 대해 궁금해 하실 분들이 많으실 것 같습니다. 가비지 컬렉션은 말 그대로 메모리 안에 있는 쓰레기들을, 메모리에서 완전히 털어내는 것을 뜻합니다. 좀 더, 전문적으로 얘기해보면, 메모리에 적재된 비활성 객체를 메모리에서 소거하는 것을 뜻합니다.
조금 더 자세한 이해를 위해 아래의 소스코드를 살펴 봅시다.
위 애플리케이션은 특정 캔버스 안에 랜덤 한 위치를 정해 캔버스를 약 1000개를 생성하고, 다시 지우는 애플리케이션입니다. 아울러, 캔버스를 소거 할 때엔 반드시 해당 객체에 null을 넣어 비 활성화 객체로 지정 하고 있습니다.
위의 방법대로 한다면, 비 활성화된 객체는 곧 메모리에서 소거되어 개발자가 해당 객체에 대한 메모리관리를 개발자가 신경 쓰지 않는 것이 맞지만, 아쉽게도 Flash Player 에서는 비 활성화 객체가 메모리에서 소거되는 시점을 알 수 없습니다.
(테스트는, 플렉스 빌더에서 프로파일링 기능을 이용하거나, 현재 메모리 사용량을 찍어서 알 수 있습니다.)
이렇게, 비활성화 된 객체가 바로 메모리에서 소거되지 않는 이유는 Flash Player의 GC 방식 때문인데, 어도비 에서는 Flash Player의 가비지 컬렉션을 Flash Player가 사용할 수 있는 가용 메모리를 넘어 섰을 때, 적제된 비 활성화 객체 순서대로 진행하고 있기 때문입니다.
이러한 Flash Player의 GC정책이 큰 문제가 되지 않는다고 생각하실 분들이 있겠지만, 사실 상당히 심각한 문제가 될 수 있습니다. Flash 애플리케이션 개발자들은, 가비지 컬렉션이 일어난 시점을 알 수 없기 때문에, 현재 가용 메모리를 관리할 틈이 없고, 이로 인해 애플리케이션의 메모리 설계를 잘못 하게 될 경우엔, 사용자에게 메모리와 관련해서 중대한 영향을 끼칠 수도 있습니다.
특히 AIR는 데스크탑에서 실행되는 애플리케이션인 만큼, 웹에 비해 사용자가 더욱 빈번하게 사용하고, 또 오랜 시간 사용할 가능성이 높습니다. 그리고, 잘못된 메모리 관리로 인한 리스크도 더 클수 있겠죠. 따라서, 메모리 관리가 무엇보다 중요합니다.
다행히도, AIR는 Flash Player와는 달리, 개발자가 가비지 컬렉션이 발생하는 시점을 지정 할 수 있습니다.
시점이라고 하니 다소 이상한가요? Adobe AIR 애플리케이션에서 System.gc 메서드를 호출하게 되면, 현재 메모리에서 비 활성화 된 메모리를 즉각적으로 소거하게 됩니다.
위의 예제는 앞서 살펴본 Flash Player에서 GC 테스트와 같은 예제입니다. 다만, 캔버스를 제거하고, 비 활성화 객체로 만든 후, 가비지 컬렉션을 실행하는 것을 볼 수 있습니다.
실제 위의 예제를 실행하고, 메모리 변화를 관찰해 보면, 비 활성화 된 객체가 즉각적으로 메모리에서 소거되는 것을 알 수 있습니다.
이처럼, AIR 개발자는 System.gc 메서드를 이용해, 가비지컬렉션이 발생하는 시점을 지정 할 수 있고, 메모리 관리도 좀 더 효율적으로 할 수 있습니다.
다만, 주의해야할 점은 System.gc는 개발 과정중 ADL에서 실행하거나, 클라이언트에 설치된 AIR 애플리케이션, 혹은 디버그용 플래시 플레이어에서 가능합니다.
XML의 가비지 컬렉션
지금까지, AIR의 가비지 컬렉션에 대해서 알아봤습니다. Flash Player는 개발자가 가비지 컬렉션 시점을 알 수 없지만, AIR는 개발자가 가비지 컬렉션이 일어나는 시점을 지정 할 수 있습니다.
아울러 Flash Player와는 별도로, 얼마전 릴리즈된 AIR 1.5.2에서는 XML 객체에 가비지 컬렉션 시점을 지정 할 수 있는 disposeXML 메서드가 추가되었습니다.
그런데, 왜 AIR 1.5.2에서 XML 객체만 별도로 가비지 컬렉션을 할 수 있는 메서드가 추가되었는지 궁금해 하실 분들이 많을 것 같습니다.
XML 객체는 각 노드안에 자식 노드들이 존재하는 상당히 복잡한 자료구조로, 실제 AVM(AAVM)에서는 XML의 각 노드와 자식노드들이 포인트 형태로 묶여 있다고 합니다. 즉, 메모리에서도 각 노드별로 뛰엄하게 띄워져 있습니다.
따라서 가비지 컬렉션을 시행하는 중에서도, XML 객체는 상당히 까다로운 작업을 해야 하고, 이로 인한 메모리릭도 상당히 빈번하게 발생한다고 합니다.
어도비에서 XML 객체에 한해 별도로 GC를 할 수 있게 한 이유도, System.gc를 이용해 가비지컬렉션을 실행하거나, 메모리 임계치 도달에 의해 가비지컬렉션이 도달할 때, XML 객체로 인한 메모리 릭을 미연에 방지하기 위함이라고 하네요.
아래의 예제를 살펴봅시다.
위 AIR 애플리케이션은, 사용자의 문서 폴더에 저장된 특정 XML파일을 읽어 오고, 비 활성화 객체로 만든 후, XML 객체만 가비지 컬렉션을 실행하게 됩니다.
disposeXML 메서드를 호출하면, 위의 그림처럼 XML 객체가 메모리에서 완전히 소거되는 것을 볼 수 있습니다. 다만, disposeXML 메서드는 현재 비활성화 된 모든 XML 객체가 아닌, 특정 XML 객체에 한해 GC가 발생한다는 점을 주의하여야 합니다.
참고로, disposeXML 메서드를 사용하려면, AIR 1.5.2 SDK로 반드시 업데이트 하셔야 합니다.



