리팩토링을 위한 성능 기반의 무브 메소드 영역 추출 및 분석 연구 (refactoring for performance-based move method region extraction and analysis of research) 권 예 진 이 준 하 박 용 범 단국대학교 전자계산학과 충남 천안시 동남구 단대로 119 kwon6030@dankook.ac.kr 서강대학교 컴퓨터공학과 서울특별시 마포구 백범로 25 zuna.lee@gamil.com 단국대학교 전자계산학과 충남 천안시 동남구 단대로 119 ybpark@dankook.ac.kr 요약: 소프트웨어가 복잡해지고 대형화됨에 따 라 다양한 소프트웨어 구조 개선 방법이 연구되 고 있으며, 특히 객체지향 시스템에서의 복잡도 를 낮추고 가독성, 구조, 성능, 유지보수, 추상 성 등을 향상시킬 수 있는 리팩토링 (Refactoring)이 많이 사용되고 있다. 리팩토 링은 객체지향 방법론에서 사용되는 높은 응집 도와 낮은 결합도 원칙("High Cohesion, Low Coupling principle", Larry Constantine, Edword Yourdon, 1970)에 따라 기존의 소프트 웨어를 개선하고 보수하는 것을 목표로 삼고 있 지만 객체지향 언어로서 가장 많이 사용되고 있 는 자바(Java) 자체의 특징과 객체들의 관계를 기반으로 연관성을 찾기 위한 연구는 진행된 바 가 없다. 본 연구에서는 자바에서 이슈 중에 하나인 메모리 관리와 GC(Gabage Collection)를 기반으로 각 객 체와 메모리 관계를 주요 팩터로 선정하여 리팩토 링을 시도하는 기법을 제안한다. 또한 리팩토링의 무브 메소드와 결합도를 이용하여 클래스간의 실 제 소프트웨어 시스템 내부 동작 메소드 호출을 통해 추출된 복합 요소를 통해 클래스드 사이의 무브 메소드 영역을 선정하고 무브메소드를 한 결 과 성능 영향도를 분석하였다. 핵심어: 리팩토링(Refactoring), 무브 메소드 (Move method), 결합도(Coupling), 메모리 성능 (Memory Performance) 1. 서 론 소프트웨어가 복잡해지고 대형화됨에 따라 다 양한 소프트웨어 구조 개선 방법이 연구되고 있 으며, 특히 객체지향 시스템에서의 복잡도를 낮 추고 가독성, 구조, 성능, 유지보수, 추상성 등 을 향상시킬 수 있는 리팩토링(Refactoring)[1] 이 널리 사용되고 있다. 리팩토링은 결과의 변 경 없이 코드의 구조를 재조정하여 가독성을 높 이고 유지보수를 편하게 하는 기법으로, 1990년 대 초반부터 연구되기 시작하였으며 소프트웨어 의 주요한 개발 분야로서 그 연구범위를 확대시
키고 있다[2][3]. 리팩토링은 객체지향 방법론에서 사용되는 높은 응집도와 낮은 결합도 원칙("High Cohesion, Low Coupling principle", Larry Constantine, Edword Yourdon, 1970)에 따라 기존의 소프트웨어를 개선하고 보수하는 것을 목표로 삼고 있다. 지금까지 리팩토링 연구는 주로 객체들의 구성 요소들을 정의하고 구성요 소들 사이의 응집도와 결합도, 복잡도를 측정 할 수 있는 메트릭을 이용하여 후보영역을 탐 색하고 자동으로 리팩토링을 할 수 있는 방법 으로 진행되어 왔다[4][5]. 또한 마틴 파울러 가 정의한 코드의 나쁜 냄새를 디자인 패턴으 로 재구성해 필요한 후보 영역을 재정의 하거 나[6], 각 객체들 사이의 유서성과 거리를 동 시에 측정하여 리팩토링을 하는 기법[7]을 제 시하는 등 다양한 시도를 거듭해왔다. 리팩토링에는 다양한 기법들이 연구되어 왔지 만 현재 객체지향 언어로서 가장 많이 사용되고 있는 자바(Java) 자체의 특징과 객체들의 관계를 기반으로 연관성을 찾기 위한 연구는 진행된 바 가 없다. 자바에서는 자동화된 메모리 관리 프로 그램인 JVM(Java Virual Machine)이 제공되며, JVM이 동작하는데 있어 GC(Garbage Collection) 는 Java 언어의 메모리 구조와 성능에 중요한 부 분을 차지하고 있다. 많은 프로그래머는 기존의 C언어나 C++언어처럼 프로그래머가 메모리 할당 과 반환을 일일이 처리하지 않고 비사용중인 메 모리는 자동으로 GC가 처리해 줄 것이라고 예상 하기 때문에 자바를 편리하다고 생각하지만 의외 로 잘못된 변수 선언이나 객체 참조 관계 때문에 비사용중인 메모리가 반환되지 않아 메모리 누수 (Memory Leak)가 발생하는 경우가 많다[8]. 이 러한 문제는 결국 소프트웨어가 대형화되고 실시 간 처리가 필요한 시스템과 같은 경우에는 치명 적인 결함을 유도할 수 있는 문제가 된다. 본 연구에서는 자바에서 이슈 중에 하나인 메모 리 관리와 GC(Gabage Collection)를 기반으로 각 객체와 메모리 관계를 주요 팩터로 선정하여 리팩토링을 시도하는 기법을 제안한다. 또한 리 팩토링을 하기 위한 기준으로 메모리 성능을 개 선할 수 있는 기준을 제시하며 리팩토링의 무브 메소드와 결합도를 이용하여 클래스간의 실제 소 프트웨어 시스템 내부 동작 메소드 호출을 통해 추출된 복합 요소를 통해 클래스를 분해하여 재 구성하고 리팩토링 하는 재구성 기법에 대하여 정의한다. 2. 관련 연구 2.1. 리팩토링과 무브메소드 리팩토링은 프로그램의 행위를 보전하면서 프로그램의 가독성, 구조, 성능, 유지보수성, 추상성 등을 향상시키는 향상시키는 방법이다 [1]. 리팩토링은 프로그램의 가독성을 높일 뿐만 아니라 개발 속도를 높일 수 있도록 효 율적이고 통제된 방법을 제공하여 소프트웨어 의 가치를 높인다는 장점을 가진다[9]. 여러 가지 리팩토링 기법중 하나인 무브 메소드(Move Method)는 클래스 내에 메소드를 다른 메소드로 이동시키는 방법이다. 무브 메 소드는 메소드가 자신이 정의된 클래스보다 다른 클래스의 기능을 더 많이 사용하고 있다 면, 이 메소드를 가장 많이 사용하고 있는 클 래스에서 비슷한 몸체를 가진 새로운 메소드 를 만들고 이전 메소드는 간단한 위임으로 바 꾸거나 완전히 제거하는 것을 의미한다. 무브 메소드는 클래스가 너무 많은 동작을 가지고
있거나, 다른 클래스와 공동으로 작업하는 부 분이 너무 많아텨 단단한 결합이 되었을 경우 사용하게 된다. 또한 자신이 속해있는 클래스 보다 다른 클래스를 더 많이 참조하는 메소드 가 존재한다면 리팩토링을 하게 된다[2]. 리팩토링에서 무브 메소드를 결정 짓는 요소 는 클래스간의 결합도이다. 너무 단단하게 결합 되어 있는 클래스들은 전체적인 프로그램의 성능 을 저해시키는 요소가 된다. 따라서 결합도를 측 정할 수 있는 메트릭을 통해 단단하게 결합되어 있는 클래스들을 탐색하고 자동으로 리팩토링을 하기 위해 무브 메소드를 통해 기존의 소프트웨 어를 개선 할 수 된다. 2.2. 결합도 메트릭 결합도는 모듈 또는 클래스들이 상호 의존하 는 정도를 나타내는 것으로 모듈이나 클래스들 간의 결합도를 최소화시켜야 모듈의 독립성이 증 가되며, 시스템 전체의 성능이 좋아지고 복잡도 가 줄어든다. 그러나 두 개의 모듈이 서로 강하 게 연결되어 상호간의 메시지 전송이 잦고, 주고 받는 데이터들의 수가 많은 경우는 시스템 자체 에 이해도가 떨어지며, 복잡도가 증가하고 객체 지향 패러다임에서 적절하게 설계되었다고 할 수 없다[10]. 결합도 메트릭은 지금까지 많은 연구가 진행 되어 왔다. 다양한 방법으로 정적 소스코드를 분석하거나 소프트웨어 실행시에 나타나는 결합 도를 측정하기 위한 동적 메트릭 연구 등 코드 내의 결함을 자동으로 찾기 위해 연구되고 응용 되었다. 결합도 메트릭 중 클래스의 메소드 호출이나 메시지 전달 방식을 측정하는 메트릭으로는 MM(Method-Method interaction), IPC(Information Flow-based Coupling), MPC(Message Passing Coupling)가 있다. MM은 클래스 C에서 구현된 클래스 D의 정적 호출 메 소드나 또는 같은 메소드에 포인터를 받는 것으 로 정의한다. MM은 정의에서 분명하게 호출의 빈도를 계산하지 않고 클래스 메소드나 시그니 처(문법)을 통해 계산되므로 정적 결합도 측정 방법에 해당한다. 이 MM의 측정 메트릭의 일반 화 공식은 다음과 같다[11]. (1) IPC는 메소드를 호출하는 수를 카운트하여 클 래스들의 가중치를 매개변수의 수에 따라 다르 게 부과하는 정보흐름에 기반한 커플링 측정 방 법이다. 클래스 사이의 정보흐름, 즉 메소드 호 출의 빈도를 이용하여 측정하는 것이기도 하자 만 객체 호출에서 클래스의 메소드로부터 계산 되기도 한다[12]. MPC는 다른 클래스에서 한 클 래스의 메소드에서 호출하는 문장의 개수로 결 합도를 측정하는 방법이다. 메시지 전송의 문장 은 실제 객체의 메소드 호출의 실행 수를 반영 하지 않는다[13]. 또한 객체들 사이의 참조 관계나 어트리뷰트 접근과 같은 호출 관계를 포함하는 메트릭으로 는 RFC(Response for Class), CBO(Coupling Between Object), CP(Coupling Factor)가 있 다. RFC는 클래스의 반응을 나타내는 원소를 포 함하는 집합의 개수를 측정하는 방법이다. 반응 집합(Response set)은 모든 지역적인 메소드에 서 다른 지역적인 메소드를 호출하는 클래스들 로 이루어져 있다. 즉 RFC는 지역 메소드와 이 지역 메소드에서 호출하는 따른 지역 메소드들 로 구성되어 있다[14]. CBO는 두 클래스는 한
클래스의 메소드를 사용하거나 또는 인스턴스 변수의 메서드가 다른 클래스에 의해 정의되면 결합된다. 로 정의 된다. 이 측정 방법은 실행 되는 동안의 호출의 개수를 계산하지 않기 때문 에 동적인 결합도 측정 척도는 아니지만 호출된 메소드의 변수의 개수로 계산된다[13]. CP(Coupling Factor)는 결합도를 메시전달 또는 클래스 인스턴스간의 의미있는 연결로 의해 정 의된다. 따라서 동적 결합도 측정에 이용되는 방법이다. CP는 클래스들의 상호작용에 가능한 다양한 방식의 정보 교환을 포함하는 결합도 측 정 방식이다. CP는 다음 식2와 같이 정의되어 있다[15]. (2) 각 클래스들의 구조적인 결합도를 측정하는 메트릭으로는 DIT(Depth of Inheritance Tree), NOC(Number of Children)가 대표적이다. DIT는 클래스의 상속관계의 계층적 구조에서의 위치를 측정하는 메트릭이다. DIT 메트릭이 클수록 클래 스를 유지하는 것이 더욱 어려워 진다. 최상위 루트 클래스의 경우 DIT는 0이 된다. NOC(Number of Children)는 현재 클래스에서 연 관된 자식클래스를 측정할 수 있는 메트릭이다. DIT가 계층적 구조에서 클래스의 위치를 측정하 는 메트릭이라면 DIT는 직접적으로 연관된 자식 클래스의 개수를 가지고 측정하는 방법이다[14]. 기존의 결합도 측정 방식은 소스 코드 내의 메소드 호출이나 메시지 전송, 어트리뷰트 접근 과 같이 소스코드 자체의 결합도에 한정되어 있 다. 소스코드의 결합도를 측정하는 것은 실제 실행중인 소프트웨어의 결합도와는 차이가 있을 수밖에 없고, 클래스간의 참조 관계가 없다고 하더라도 실제 수행중에 나타나게 되는 객체들 의 관계는 있을 수도 있다. 따라서 본 논문에서 는 실제 수행중인 프로그램의 객체들의 관계를 기반으로 결합도를 측정하고 메모리 성능을 향 상시킬 수 있는 프로세스를 제안한다. 2.3. 객체 관계 두 객체간의 결합도는 객체간의 관계를 통해 드러나게 된다. 일반적으로 객체의 관계는 크게 연관관계와 상속 관계로 표현된다. 결합도를 측 정하는 메트릭은 객체들의 관계에 따른 수치를 일반화 하는 것으로, 객체들간의 의존관계나 연 관관계를 기반으로 측정된다. 따라서 기존의 객 체 관계를 분석하고 정의하는 것은 결합도를 이 해하는 방법 중 하나이다. 객체 관계에서 일반 관계(General Relationship)은 연관 관계(Association), 집 합 연관(Aggregation), 합성 연관 (Composicion)으로 나누어진다. 연관 관계는 클 래스 간의 정적인 관계를 설명하는 가장 추상적 인 방법으로 두 클래스 간의 또는 더 많은 클래 스들 사이의 의존관계나 관계 종류의 상태를 나 타낼 수 있는 관계이다. 연관관계는 인스턴스를 파라미터로 가지고 있거나 인스턴스를 반환 받 는다. 집합 연관은 전체 부분 관계를 나타내며, 연관 관계보다 더 구체화 시켰을 경우 사용된 다. 합성 연관은 한 클래스가 다른 클래스를 독 점적으로 소유하고 있지 않다는 점을 강조하기 위해 사용된다. 또한 모든 연관 관계는 합성 연 관으로 대체될 수 있지만 합성 연관 관계는 일 반 연관관계로 대체될 수 없다. 집합 연관은 참 조 인스턴스를 독점적으로 소유하고 있는 클래
스와 해당 클래스가 참조되어 있는 클래스의 관 계를 나타낸다. 집합 연관의 경우 클래스의 변 경 사항들이 시스템의 나머지 부분이 전파되지 않는다. 상속 관계(Inheritance)는 일반화 관계 (Generalization)과 실체화 관계(Realization) 두 가지로 나눌 수 있다. 일반화 관계는 추상적 인 클래스에서 일반화된 구체적인 클래스의 관 계로 정의되기 때문에 상속을 의미한다. 예를 들어 하나의 클래스가 다른 클래스로 확장할 때 일반화 라고 한다. 실체화 관계는 인터페이스를 이용한 관계이며 클래스들이 구현해야 하는 행 동을 순서대로 정의하여 제공한다. 즉 객체가 서로 통신하는 방법을 지정한 것이다.[16] 3. 객체 참조 관계에 따른 리팩토링 영 역 정의 자바에서는 자동화된 메모리 관리 프로그램인 JVM을 통하여 플랫폼에 상관없이 다양한 OS 환 경에서 실행 가능하기 때문에 가장 널리 사용되 는 프로그래밍 언어이며, 기존의 다른 프로그래 밍 언어보다 속도가 느린 단점을 가지고 있다. 자바에서 성능을 결정짓는 주요 요소중 하나인 GC의 알고리즘은 객체들의 참조관계를 기준으로 메모리를 할당하거나 반환한다. 따라서 본 연구 에서는 메모리 상주를 결정짓는 객체 참조관계 를 기준으로 하여 리팩토링을 하는 프로세스를 제안한다. 본 연구에 앞서 실제 자바 실행 환경 에서 GC에 의한 메모리 결정 관계를 정의하고 해당 문제를 리팩토링의 주요 요소로 결정짓기 위해 프로그램의 실제 수행 단계에서의 객체들 의 참조 관계와 메모리 사용량을 비교 분석한 다. 3.1. 리팩토링 프로세스 파울러는 무브 메소드의 적용 요인을 메소드 가 자신이 정의된 클래스보다 다른 클래스의 기 능을 더 많이 사용하고 있는 경우 로 정의하고 있다[2]. 이러한 무브 메소드의 적용 요인을 프 로그램 실행 시에 나타날 수 있는 메모리 관계 를 통하여 정의한다. 실제 프로그램의 동작 과 정에서 작은 메모리 영역을 차지하고 있는 클래 스에서 큰 메모리를 차지하고 있는 클래스의 하 나의 기능만을 수행하기 위해 참조관계를 가지 고 있는 경우에는 GC에서 제거하지 못하고 메모 리에 상주하게 되는 경우를 초래하게 되어 성능 적인 면에서 불리하게 작용할 수 있다. 따라서 이러한 객체들 사이의 참조 관계를 통해 해당 영역을 추출하고 무브 메소드를 수행할 리팩토 링 후보영역으로 선정한다. 리팩토링의 후보 영 역을 추출하기 위해서는 프로그램 동작 과정에 서 전체적인 메소드 콜 관계를 통해 실제 동작 수행시 메모리 사용량을 비교하여 리팩 프로그 램의 수행중에 나타나는 객체들의 콜 관계에 따 라 리팩토링이 필요한 영역을 추출하고 동시에 메모리에 상주하는 메소드들을 결합한다. 해당 과정을 그림으로 나타내면 아래의 그림 2와 같 다. 그림 1. 성능 기반 리팩토링 프로세스
그림 1은 객체지향적으로 프로그래밍 된 프 로그램을 동작 과정 중에 나타나게 되는 메소드 콜 관계를 통해 동시간에 수행되는 메소드를 기 준으로 통합해 리팩토링 하기 위한 프로세스이 다. 동시간에 수행되는 메소드들의 콜 관계와 시간와 시간을 기준으로 같은 시간에 존재하게 되는 확률 계산과 함께 무브 메소드의 대상이 되는 메소드들을 추출한다. 이렇게 무브 메소드 의 대상이 되는 메소드를 통해 결합도가 높은 클래스들을 중심으로 무브 메소드의 영역을 한 정한다. 결과적으로 무브 메소드의 영역을 지정 하고 해당 메소드를 다른 클래스로 옮겼을 경우 같은 시간에 존재하며, 클래스간의 결합도를 낮 추게 되어 메모리 성능이 향상된 프로그램으로 수정할 수 있게 된다. 3.2. 리팩토링을 위한 영역 정의 본 연구에서는 프로그램이 실행중에 나타나게 되는 메소드 콜 관계와 실행되는 시간에 따라 같은 시간대에 존재하는 메소드들의 결합도와 확률을 측정하여 리팩토링을 위한 후보 영역으 로 선정한다. 실제 두 개의 클래스 인스턴스의 메소드들의 실행 시간을 간단하게 그림으로 표 현하면 아래의 그림 2와 같다. 그림 2. 클래스별 메소드 수행시간 위의 그림과 같이 시간에 따른 메소드의 수행 시간을 보면 각 클래스의 인스턴스에 존재하는 메소드별로 수행되는 시간이 각기 다르게 나타 나게 된다. 실제 JVM에 의해 프로그램이 실행 될 경우 ClassA에 대한 참조를 ClassB에서 가지 고 있다면 두 클래스 모두 GC에 의해 제거되지 않고 메모리상에 존재하게 된다. 또한 ClassA의 모든 기능이 끝났다고 하더라도 ClassB의 호출 로 인해 메모리에 상주하게 되면 메모리 누수가 발생할 가능성이 높아진다. 따라서 각 시간별로 메소드들이 같이 존재할 확률을 계산하고 또한 각 객체들 사이의 결합도, 어트리뷰트에 접근하 는 내부 결합도를 복합적으로 측정하여 동시에 수행되는 기능을 묶어 새로게 소스코드를 수정 하는 리팩토링 기법을 제안한다. 먼저 각 클래스의 메소드를 아래의 식 3과 같이 정의한다. (3) 각각의 메소드를 메소드 호출 시간에 따라 처 음 메소드가 호출되는 시간과 메소드 호출이 끝 나는 시간으로 표현한다. 메소드의 호출 시간과 메모리에 상주하게 되는 시간을 통해 같은 시간 에 호출된 메소드가 얼마나 있는지, 서로 다른 클래스에 존재하는 메소드들이 같은 시간에 존 재하는지를 측정한다. 메소드의 호출에 따른 시 간 정의와 호출 관계의 데이터를 통해 아래의 식 4와 같이 각각의 메소드가 같은 시간에 존재 할 확률을 계산하게 된다. (4) 메소드 와 가 같은 시간에 존재할 확률 은 전체 시간은 만큼 쪼개고 해당 구간에 와 가 존재할 확률을 곱한다. 그 후 전체 구간 동안의 두 메소드가 존재할 확률을 계산한다. 확률 계산적으로 같은 시간에 같은 클래스에 속해있지 않은 두 메소드가 존재할 확률이 더
크고, 같은 클래스내의 다른 메소드들과 존재 할 확률보다 다른 클래스내의 존재하는 메소드 와 결합되어 있다면 해당 클래스로 메소드를 옮기는 것으로 무브 메소드의 영역을 정의하게 된다. 전체 계산과정을 알고리즘으로 표현하면 아래와 같다. if if 그림 3. 무브 메소드 추출 알고리즘 알고리즘을 살펴보면 처음 각 클래스 내부에 서 메소드들끼리 같은 시간대에 존재할 확률을 계산한 와 가 있다. 위에서 정의된 식 4에 따라서 각기 다른 클래스에 존재하는 메소 드들 사이의 확률을 계산한 후에 내부 메소드들 과 확률계산 결과와 비교 한 후 만약 다른 클래 스에 존재하는 두 메소드의 확률 결과가 더 크 다면 결과적으로 무브 메소드를 수행할 후보 영 역으로 추출된다. 4. 무브 메소드와 결합도 관계 무브 메소드를 수행해야 하는 후보 영역을 추 출하게 되면 두 메소드들 사이의 참조 관계나 호출 관계가 존재하는 경우도 있지만 단순히 메 소드들이 동시에 존재하게 되는 경우도 있다. 만약 메소드들 사이에 아무런 연관도 없지만 여 러 스레드에서 동시에 동작하기 때문에 무브 메 소드를 하기 위한 후보 영역으로 선정되고, 메 소드를 다른 클래스로 옮기게 된다면 오히려 복 잡도가 증가하고 서로 관련 없는 클래스들 사이 의 결합도가 증가하게 되는 문제가 발생 할 수 있다. 따라서 본 연구에서는 무브 메소드의 후 보영역으로 추출된 두 메소드들의 리스트를 통 해 두 메소드의 결합관계를 측정하고 결합관계 가 존재한다면 최종적으로 무브 메소드의 영역 으로 선정하고 리팩토링을 수행하도록 한다. 결합도를 측정하는 방법으로는 정적 메트릭을 사용하며, 정적으로 측정하여 서로 결합되어 있 는 클래스의 메소드들 사이의 확률 분포를 통해 무브 메소드를 할 영역을 결정한다. 4.1. 결합도를 이용한 결정 3장에서 추출된 무브 메소드에서 결합도를 기 반으로 최종 무브 메소드 결정을 하기 위한 프 로세스는 아래의 그림 3과 같다. 그림 4. 결합도 결정 프로세스 그림 3의 알고리즘에 따라 프로그램의 메소드 콜 관계를 가진 시퀀스를 통해 실제 메소드들의 호출 관계를 분석하고 같은 시간대에 존재하는 메소드들의 확률 계산을 한다. 확률적으로 같은 시간대에 존재하며, 같은 클래스들과 동시에 실 행되지 않는 경우 최종적으로 무브 메소드의 후 보 리스트에 존재하게 된다. 그러나 리팩토링이
필요한 후보 영역일지라도 서로 연관성이 존재 하지 않는 경우 리팩토링을 시도할 경우 오히려 프로그램의 성능을 떨어뜨릴 수 있다. 따라서 결합도 측정을 통해 서로 결합되어 있는 클래스 들 사이의 메소드일 경우 무브 메소드를 통한 리팩토링을 한다. 먼저 위의 예제 프로그램을 메모리 측정 프로 그램인 Jprofiler를 통해 수행중에 메모리 사용 량을 측정하면 아래의 그림 6과 같다. 5. 사례 연구 간단하게 본 연구의 제안을 증명하기 위해 큰 클래스와 작은 클래스 사이의 일반 연관 관계를 기반으로 메모리 사용량과 메소드 콜 관계를 분 석하였다. 전체 클래스의 구조는 아래의 그림 5 와 같다. 그림 5. 예제 프로그램 LargeClass의 메소드인 testlarge1()은 LargeClass의 inner 클래스인 GeneralClass를 호출하며, 간단한 기능을 수행한다. SmallClass 의 testsmall1() 메소드는 LargeClass의 testlarge2() 메소드를 호출한다. 전체적인 프로 그램의 흐름은 처음 LargeClass를 생성하고 내부 적인 기능을 수행한다. LargeClass는 내부적으로 해쉬맵을 사용하여 대용량의 데이터를 생성하고 처리한다. Large클래스의 수행이 끝난 뒤에 Small 클래스에서 내부적으로 메소드를 호출하고 기능을 수행하게 되는데 LargeClass의 testlarge2()메소드를 호출하기 때문에 LargeClass는 메모리에 SmallClass가 종료될 때 까지 상주하게 된다. 그림 6. 메모리 사용량과 GC 동작 메모리 사용량은 지속적으로 증가하며 GC의 동 작이 일어난다고 해도, 실제 프로그램 내의 참조 관계로 인해 메모리 사용량이 증가된다. SmallClass는 지속적으로 생성되었다가 사라지는 주기가 짧은 클래스이지만 LargeClass를 참조하 기 때문에 LargeClass가 GC에 의해 삭제되지 못 하고 지속적으로 존재하게 된다. LargeClass 내에서 testlarge2() 메소드는 LargeClass 내의 다른 메소드들이 모두 끝났음 에도 불구하고, 지속적으로 메모리에 존재하게 된다. 또한 SmallClass의 호출에 따른 testlarge2() 메소드의 관계 때문에 오히려 LargeClass 내에 존재하는 testlarge2()메소드 가 SmallClass의 다른 메소드들과 같이 동작하 는 상주 시간이 더 긴 것을 알 수 있다. 프로그 램에서 무브 메소드를 통해 리팩토링을 해야하 는 부분은 LargeClass의 testlarge2()메소드를 SmallClass로 옮기는 것이다. testlarge2() 메 소드를 SmallClass로 옮기면 결합 관계가 사라 지게 된다. 처음 원래 프로그램에서 메소드를 옮 긴 후의 메모리 사용량과 GC의 활용 결과를 분석해 보면 아래의 그림 7과 같다.
그림 7. 무브 메소드 결과 그래프 상으로는 처음 결과와 무브 메소드를 한 결과의 차이가 거의 없다. 그러나 실제 메모 리 사용량과 수치값을 비교하면 메모리 사용량 이 줄어든 것을 알 수 있다. 또한 LargeClass 의 내부 기능 수행이 끝나게 되면 LargeClass 는 SmallClass와 참조관계가 존재하지 않으므로 GC에 의해 메모리 해제가 된다. 무브 메소드를 하기 전과 하고 난 후의 메모리 사용량을 비교 하면 아래의 표 1과 같다. 실험 메모리 사용량 FreeSize Move method 전 1.141GB 0.593GB Move method 후 1.060GB 0.553GB 표 1. 메모리 사용량 비교 위의 표 1과 같이 무브 메소드를 하기 전과 하고 난 후의 메모리 사용량을 측정해 보면 실 제 무브 메소드를 수행한 후에 메모리 사용량이 감소한 것으로 측정된다. 이 결과 값은 LargeClass에 대한 SmallClass의 참조 관계를 끊고 메소드를 옮김으로서 실제 같이 동작하는 메소드들을 한 클래스로 묶어 쓸데없는 참조 관 계나 메모리 낭비를 줄여주는 효과를 볼 수 있 다. 6. 결 론 지금까지 리팩토링을 위한 성능 기반의 무브 메소드 영역을 추출하고 실제 적용하여 메모리 의 효율성과 성능에 어떠한 영향을 끼치는지 분 석하였다. 리팩토링의 영역을 선정하기 위해 프 로그램 수행 중에 같은 시간에 나타나게 되는 메소드들의 확률 분포와 결합도를 기반으로 무 브 메소드의 주요 팩터로서의 정의와 프로세스 를 제안하였으며, 결합도를 참고로 하여 실제 무브 메소드를 할 결정 요인으로 사용하였다. 현재까지 리팩토링 연구는 주로 객체들의 구 성 요소들을 정의하고 구성요소들 사이의 응집 도와 결합도, 복잡도를 측정할 수 있는 메트릭 을 이용하여 후보영역을 탐색하고 자동으로 리 팩토링을 할 수 있는 방법으로 진행되어 왔다. 그러나 본 연구에서는 메모리 성능과 각 객체들 의 메소드 참조 관계를 리팩토링의 주요 팩터로 서 선정하고 이를 적용하는 프로세스를 제안하 였다. 이는 리팩토링을 위한 새로운 지표로서 실제 프로그램의 동작과 성능에 영향을 줄 것으 로 기대된다. 향후 연구로는 자동화된 소스 분석과 성능에 따른 확률 분포를 제공할 수 있는 툴을 제공할 예정이며, 또한 실제 메소드를 다른 클래스로 옮기기 위해 객체들의 관계와 메소드들의 관계 를 분석하고 자동화하기 위한 연구를 할 예정이 다. 참고문헌 [ 1] Bindu and Mehra, A Critique of Cohesion Measures in the Object-Oriented paradigm, Masters Thesis, Department of Computer Science, Michigan Technologial university, 1997.
[2] Martin Fowler, "Refactoring Improving the Desinge of Existing Code", Addision Wesley, 1999. [3] W.G. Griswold, "Program Restructuring as an Aid to Software Maintenance", PhD Thesis, Dept. of Computer Science & Engineering, University of Washington, 1991. [4] Frank Simon, Frank Steinbruckner, Claus Lewerentz, Metrics Based Refactoring, IEEE, 2001 [5] Yoshiki Higo, Toshihiro Matsumoto, Shinji Kusumoto, Katsuro Inoue, Refactoring Effect Estimation based on Complexity Metrics IEEE, 2008. [6] Min Zhang, Nathan Baddoo, Paul Wernick, etc., Improving the precision of Fowler s Definitions of Bad Smells, IEEE, 2009 [7] Nikolaos Tsantalis, etc., Identification of Move Method Refactoring Opportunites, IEEE T R A N S A C T I O N S O N SOFTWARE ENGINEERING, VOL.35, NO.3, MAY/JUNE 2009 [8] Wim De Pauw, Gray Sevirsky, Visualizing reference patterns for solving memory leaks in Java, ECOOP, 1999 [9] 정영애, 박용범, 클래스 간 메소드 위치 결정 방법의 비교, 한국콘텐츠 학회논문지 vol.6 No.12, 2006 [10] Roger S. Pressman, Software Engineerignn A Practitioners Approach, Fourth Edition McGrawHill, 1997 [11] Briand, L., P.Devanbu, and W.Melo, An Investigation into Coupling Measures for C++, Proc. Of the 19th International Conference on Software Engineering, ICSE 97, Boston, May 1997, pp412-421 [12] Lee, Y., B. Liang, and S. Wu, Measuring the Coupling and Cohesion of an Object-Oriented Program Based on Information Flow, Proc. Of International Conference on Software Quality, Maribor, Slovenia, 1997 [13] Li, W., and S. Henry, Object Oriented Metrics that predict Maintainability Journal of Systems and Software, Vol23, No. 2, 1993, pp111-122 [14] Chidamber, S., and C.Kemerer, A Metrics Suite for Object Oriented Design, IEEE Transactions on Software Engineering, Vol 20, No 6, June 1994, pp476-493 [15] Ruchika Malhotra, "Empirical Study of Object-Oriented Metrics", Published by ETH Zurich, Chair of Software Engineering, 2006 [16] OMG, OMG Unified Modeling LanguageTM(OMG UML), SuperStructure, August 2011.