블랙베리 OS에서 기본으로 KSC5601 인코딩을 지원하지 않기 때문에, 간단한 코드 변환 클래스를 작성할 요량으로, KSC5601과 유니코드가 매핑된 char 테이블을 static 배열로 잡았습니다.

private static final char [] CODEMAP = {
   0x3000,0x3001,0x3002,0x00B7....
};

그런데 컴파일을 하려고 보니, static initializer가 65535 바이트를 초과했다면서 컴파일이 되지 않더군요.
깜짝 놀랐습니다. 배열 크기가 좀 크다고 컴파일이 안된다니... C/C++, C#에서는 이런 경험을 해본 적이 없었거든요.

여기저기 지인들한테 물어보고, 구글의 도움도 받아서 몇가지 실험을 해보았습니다.

1. 테이블을 파일에 기록하고, 클래스를 생성할 때 파일에서 읽어들여 초기화한다.
   가장 좋은 방법입니다. 하지만, 사용하고 있는 OS가 파일시스템을 지원하지 않거나 파일을 읽기가 복잡한 경우에는 좀 문제가 있겠죠? 그리고 static 초기화된 배열에 비해서 초기화시간도 오래 걸릴 수 있습니다.

2. 배열을 몇 구역으로 나눠본다.
  예를 들어, 1000개씩 배열을 나눠서 static 배열을 여러개 생성하는 것인데, 역시 안되더군요. 자바가 멤버들을 static 초기화할 때 아마 하나로 합쳐서 생성하도록 컴파일하는 모양입니다.

3. static 초기화를 사용하지 않고, 생성자에서 직접 하나씩 값을 넣는다.
   생성자에서 new char[MAX_RECORDS]를 한 다음에, 하나씩 값을 배열에 대입하여 초기화해 봤습니다.

class Dummy {
   private char[] map;
   public Dummy {
       map = new char[8000];
       map[0] = 0x3000;
       map[1] = 0x3001;
       ....
   }
}

   생성자에도 65535 바이트 제한이 걸려있어서 실패했습니다. 생성자가 아닌 일반 메소드로 만들어봤지만 역시 안되더군요. 일반 메소드의 코드 크기도 65535 바이트를 초과할 수 없습니다.

4. 초기화 함수를 여러개로 나눠서 생성자에서 부른다.
   배열을 초기화하는 함수를 65535 바이트가 넘지 않게 여러개로 나눠서 만드는 방법을 실험해 봤습니다.
즉, 배열요소를 1000개씩 초기화하는 함수를 8-9개 만들어서 생성자에서 한꺼번에 호출해 봅니다.

class Dummy {
   private char[] map = new char[8000];
   public Dummy {
       init1();
       init2();
       ....
   }
   private void init1() {
       map[0] = 0x3000;
       map[1] = 0x3001;
       ...
   }
   private void init2() {
       map[0] = 0x300D;
       map[1] = 0x300E;
       ...
   }
   ...
}

오호라~ 이 코드는 컴파일이 됩니다. 일반적인 환경에서는 거대 배열이 있을 경우 이런 식으로 초기화해서 사용하면 될 듯 싶습니다.

그렇지만.... 블랙베리 JDE에서 저렇게 작성된 클래스를 컴파일하려고 했더니, 또 컴파일 에러가 나더군요.
이유는, 생성된 바이트코드가 너무 크다는 것이었습니다. 블랙베리에서 돌아가는 실행파일은 .cod라는 확장자를 가지는데, 이 .cod 파일의 크기 제한 (공식적으로 64K)이 있었습니다. 아쉬운 순간~

5. 배열을 조각조각내고 각각 클래스로 감싼다.
   4번까지 실패하고서, 이제 자바 내부 소스를 보던지 아니면 파일을 이용해야겠다... 하고 생각하던 순간, 이렇게해보면 어떨까 하는 생각이 났습니다.
   먼저 배열을 담을 클래스들을 생성하고 배열을 1000개씩으로 잘라서 각각 static 멤버로 선언해 주었습니다. 이렇게 하면 static initializer의 크기 제한에 걸리지 않게 됩니다.

// 1000개씩 잘라서 클래스로 다 만듭니다.
class Table1 {
   public static char[] table = {
       0x3000,0x3001....
   }
}
class Table2 {
   public static char[] table = {
       0x300D,0x300E....
   }
}

   실제 배열을 사용할 경우에는 배열 인덱스의 구간을 조사한 다음에 알맞은 클래스의 static table 필드를 다시조회해야 되는 귀찮음이 있습니다만, 어쨌든 저런 방법으로도 큰 배열을 코드 상에서 static으로 초기화할 수 있습니다.
   cod 파일의 크기 제한은 어떻게 됐을까요? 4번 방법의 1/5로 줄어들더군요. 똑같은 크기의 배열을 선언한 것이지만,4번의 경우에는 일일히 하나씩 대입해주기 때문에, static으로 초기화하는 5번 코드보다 코드 사이즈가 많이 커졌던 것이죠.

  성공!!!! 몇 시간의 실험을 거친 끝에 어쨌든 간단한 코드 변환 클래스를 테스트할 수 있었답니다~

이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by leigh
◀ PREV : [1] : [2] : [3] : [4] : [5] : [6] : [7] : ... [9] : NEXT ▶

BLOG main image
by leigh

공지사항

카테고리

분류 전체보기 (9)
블랙베리 (5)

최근에 받은 트랙백

Total : 33,251
Today : 7 Yesterday : 0