admin write
blogblogblogbloglocation loglocation logtag listtag listguest bookguest book
rss feed



몇일전 업데이트 이후로 서비스중인 프로젝트가 갑자기 메모리가 치솟는 버그가 발생

거의 5분만에 점유율이 2배가까이 늘어나버리는..

급하게 프로파일링을 돌려보았는데 갑자기 상황이 막막하네요

난 내눈이 잘못된줄 아랐네.. Instance와 Memory 사용량이 같은데...

전체 메모리와 사용메모리가 늘고 있는 ㅠ


아 정말 개발자를 안티로 만드는 언어는 파워빌더 이후 첨이네..


회사에서 이번 프로젝트 하나를 제목과 같은 환경으로 하여 개발을 하였는데

문제가 아주 상당수 나왔습니다.

기본적으로 Flex4.1 ~ 4.5대의 SDK에서의 Spark 는 디자인의 한계를 극복하는등의

장점도 다수 있으나 기존 mx 컴포넌트를 100%모두 커버할수 있을정도로 SDK자체가 개발되지 않았고

모든 컴포넌트또한 완벽히 대채가 되지 않더군요

프로젝트를 하면서 계속하여 이슈가 발생하였고 그때마다 특정한 규칙을 두고 문제를 회피하는

방법으로 하였는데 결과적으로는 썩 만족스럽지가 않네요

새로 개발될 Flex 5 에서도 이런식이면 빨리 Flex 는 접고 HTML5 로 넘어가는게

몇년후를 생각하면 좋을지도 모르겠습니다.

대충 생각나는데로 크게 Issue가 되었던 몇가지를 포스트 해볼까 합니다.


1. mx:RadioButtonGroup
RadoButtion 태그는 Spark에서 지원을 해주고 있습니다. 하지만 Spark의 RadioButton 을 사용시
그룹핑기능이 아예 빠져있기때문에 mx:RadioButtonGroup 이 하던일을 손수 코딩하여야 하는 번거로움이 있습니다. 실제로 제 경우 RadioButton 이 수십개에 달하는 페이지가 있었는데
Spark의 RadioButton을 이용 RadioButtonGroup 이 동작하지 않는것을 보고 일일이 Event를 걸어야 하나 하다가 결국 mx:RadioButton 으로 모두 변경하고 RadioButtonGroup 이벤트 몇개만으로 해결을 보았습니다. ㅠ

2. PopupManager
기존 Flex 3.5에서 개발했던 모듈과 컴포넌트를 그대로 약간에 수정을 거쳐 사용하고 있었는데
팝업되는부분들이 모두 깨져나오는 현상이 발생했습니다.
구글링을 해보니 createPopUp 시 parent의 moduleFactory 를 넘겨주어야 한다고 하네요
버그는 아니고 기존 Flex 3.x 에서 Spark로 넘어오면서 StyleManager의 형태변화로 인한것이라고 하는데요. 자세한것은 제가 머리가 좋지못해 구글링을 통해 참고를;;

3. Module - PopupManager
Module 을 이용하여 페이지를 구성시에 해당 모듈에서 Popup을 이용했을때
Popup의 create와 동시에 배경의 Style이 깨지는 문제가 있었는데요
이게 거의 모든 컴포넌트에서 동시다발적으로 발생하는 현상이더군요 ㅠ
이문제때문에 굉장히 괴로운나날을 보내야 했는데
구글링을 통한 레퍼런스조차도 너무 부족해서 해결다운 해결은 보지 못했습니다.
일단 배경의 깨짐이 발생할때의 문제는
AdvancedDataGrid 의 외각 테두리가 사라집니다. ㅠ
ColumeChart에서 LineSeries 를 혼용하여 사용시 ColumnChart의 DataProvider가 깨집니다.
(데이터는 존재하지만 화면의 그래프가 모두 바닥을 치더군요.. 아무리 디버깅해보아도 데이터는 분명히 있는데 ㅠ)
등등...
그냥 그때그때 깨졌을때의 모양을 어떻게든 복구하는 형태로 고치긴 하였습니다만 원천적인 해결방법은 아니구요 정말 사람 질리게 하더군요...

4. Chart의 LabelRenderer (AxisLabel) 메모리 누수
이것 역시 구글링을 해보면 굉장히 많은 Issue 제기가 되고있었는데 뚜렷한 해결방법이 보이질 않더군요... Chart를 지우고 차트의 child를 모두 찾아 널처리를 해보고 removeChild 도 하고
labelRenderer 지정역시 널처리를 해보고 별짓 다해보았습니다만
절대 사라지지 않는 인스턴스들... 
이런것들 보면 차라리 Flex SDK 3.x 대가 훨씬 코딩하기엔 안전성이 좋지않았나 생각해봅니다.
 
5. IE9에서의 Flash player 메모리 누수
IE9의 문제라고 보는게 더 맞을듯 합니다.
IE6, FF, IE7, IE9 에서 테스트와 개발을 하고있는데
IE9 에서만 발생하더군요.. 뭐 곧 업데이트나 픽스가 나오겠지만..


대충 생각나는것들만 이정도네요
Flex프로젝트를 할때 SDK 4~5 사이의 SDK에서 혼용방식은 절대 사용하지 마시길...

Flex4부터 SDK의 대부분의 컴포넌트들이 많이 소스형태로 나와있는데요
예전 포스팅했던 AsyncCollection 이라던가 많은 기능들은 기존 3.5 SDK버젼에 대채하여 사용하는것도 괜찮을듯합니다. 테스트해보고 문제만 없다면...

Flex를 이용 약 100여개의 차트가 한화면에 떠서 거의 무제한으로 실시간 감시가 되어야하는

프로젝트를 진행중인데 가장 문제는 GC의 해제가 잘안되는것과 소스의 덩치로 인한 메모리

점유문제였다. 코딩만으로는 한계가 있고 아무리 release 를 잘하고 최적화를 해도

사람이 하는건데 빈틈도 많은.. ㅠ

Flex의 GC 로인한 문제를 2중 어플리케이션 구조와 IFrame을 이용하여

거의 완벽(?)에 가깝게 해결을 보았는데 IE9 가 태클을 ㅠ

문제는 Flex에서 flash.system.System.totalMemory 를 체크하여 특정 점유량 이상일때

하위 어플리케이션이 새로고침되도록 해서 거의 무식하게 GC가 아닌 아예 Flash player 자체를

새로고침하는 방법을 고안하여 사용하였는데

IE6, 7, 8 에서는 잘되지만 IE9만 유독문제를 일으킨다 ㅠ

문제는 IE9의 자체 캐쉬기능때문인건지 원인파악은 안되지만 구글링해보았을때

IE9의 메모리점유율 문제가 상당히 마니 검색되어 나오는걸로 봐서 자체버그인듯한..

IE9는 특정 페이지 접속시 상당히 기본 메모리 점유량이 큰데 아래 스크린샷과 같다


같은 페이지를 띄우고 확인하는데도 불구하고 IE6에서는 111메가 가량..

IE9에서는 171메가나 된다.. 더웃긴것은 새로고침을 하여도 도메인이 바뀌지 않으면

HTML에서 메타를 이용한 no-cache 등의 설정도 거의 무용지물..

캐쉬설정을 다 꺼보아도 preloader를 타지 않는다 ㅠ 아.. 미치겠...

저 망할 171메가는 늘어나면 늘어나지 아무리 F5를 연타를 하여도 줄어들진 않는다 ㅠ 뭐이런...

IE9 이하 다른 버젼에서는 아주 잘되는데.. 새로고침시 정말 아주 무식하게 메모리 점유율이

떨어지는것이 눈으로 확인이 된다.

막 나온 IE9 버젼은 되도록이면 사용하지 않는게.. 확실히 과거버젼에 비해 안전성을 좋아진듯하지만

몇몇 금융사이트에서는 아예 윈도우7의 블루스크린을 보여주는등

믿음이 썩 가지는 않는다 ㅠ





※ 20111015 추가 

현재 IE9 에서 프래쉬의 embed 시 url 뒤에 GET방식으로 timestamp 등을 파라메터로 넣어

Cache 가 되지 않도록 하여 보완할수 있습니다.

<sqlMap namespace="board">
<typeAlias alias="Board" type="board.BoardVO"/>

<sql id="board.where">
<!-- searchValue값이 비어있지 않다면 -->
<isNotEmpty property="searchValue">
<!-- parameterClass의 searchKey값이 "all" 과 같다면 -->
<isEqual property="searchKey" compareValue="all">
WHERE title LIKE #searchValue#
OR content LIKE #searchValue#
</isEqual>
<isEqual property="searchKey" compareValue="title">
WHERE title LIKE #searchValue#
</isEqual>
<isEqual property="searchKey" compareValue="content">
WHERE content LIKE #searchValue#
</isEqual>
</isNotEmpty>
</sql>

<select id="board.getList" parameterClass="Board" resultClass="Board">
SELECT *
FROM board
<include refid="board.where" /> <!-- board.where 를 여기에 삽입한다 -->
</select>

</sqlMap>


위에 보면 #searchValue# (검색내용) 와 #searchKey# (검색항목) 가 있죠?

로직부분에서 두 값을 담아 올 수 있게
BoardVO에 searchValuesearchKey 속성을 추가하고 Get/Set메소드를 만들어 줍니다
만약 정렬(orderValue)이나 페이징(firstRow, lastRow ) 이 필요할때도 VO에 추가해주면 됩니다

DAO 메소드

public List getList(BoardVO vo) throws SQLException {
return sqlMapper.queryForList("board.getList", vo);
}



JSP페이지에 검색부분은 이런식일테고
<select name="searchKey" >
<option value="all">제목+내용</option>
<option value="title">제목</option>
<option value="content">내용</option>
</select>
<input type="text" name="searchValue" />
<input type="submit" value="검색" />

자바 소스에 추가되는 내용은 이정도겠죠?
vo.setSearchKey(request.getParameter("searchKey") );
vo.setSearchValue(request.getParameter("searchValue") );
List list = dao.getList(vo);

[출처] http://slog2.egloos.com/3572364



PS. iBatis와 Spring 으로 구성을 하여 프로젝트를 하면서

DB의 테이블 디자인이 UI를 고려하지 않은 너무 데이터 수집위주로 디자인된경우

이런 동적쿼리를 많이 쓰게 되었는데

개발당시에야 익숙해지면 어느정도 개발이 되지만

추후 문제가 생겨 수정하려하니 하나 고치면 다른 한곳에서  오류나고 ;;  그러다보니

include 를 빼고 수동으로 다 입력..

또 그러다보니 어느순간에 이건 모두가 다 동적쿼리가 아니고.. 아...

동적쿼리를 쓰게 만드는 구조나 패턴은 최대한 배제해야 하고

만일, 정말 동적쿼리가 많이 쓰이게되는경우

최고의 방법은 iBatis에서 include의 사용을 완전히 배재하고

아주 스탠다드하게 isEqual, isNotEqual 로 1차적인 if 들을 걸러 동적쿼리를 어느정도 구현하고

나머지는 java 에서 짜집기 하는것이었음

그게 더 짧은 소스를 생성해 원하는것을 얻을수 있고

더 가독성이 뛰어나고,

더 유지보수가 용이함


Flex 프로젝트를 해오면서 datagrid는 선택이 아닌 필수로 사용해오고 있다

하지만 미려함으로 인해 무거운 Flex에서 대량의 데이터를 datagrid 로 출력하기엔 무리가 있다.

그래서 고안한 알고리즘이

대량의 데이터를 blazeds로 받아와 사용자의 브라우져 위에 있는 FLEX가 모두 처리하는것이 아닌

현재 사용자가 보고 있는 페이지의 데이터만을 서버에서 보내주고

클라이언트쪽에서는 사용자의 이벤트를 받아 즉각즉각 받아오는 형태로

클라이언트의 리소스와 퍼포먼스를 잡는 방법을 생각해보았다.

spring에서 쿼리를 돌려 약 컬럼수14개의 약 15만여건의 데이터를 적절히 가져와 List에

담고 있고 이후 지정된 메서드가 사용자의 이벤트에 맞춰 해당 페이지를 List에서 sublist하여

계속해서 전달하는 방식이다.

전달은 하되 클라이언트측에서는 스크롤된 안보는 페이지에 대해서 적절히 삭제가 들어가게 되고

전체적으로는 1~200 라인정도만을 유지하여 사용자에게 보여준다.

초기개발시 스크롤 이벤트를 잡아 개발하였더니 이건 완전 ㅠ

구현은 어느정도 되나 스크롤의 모양도 엉망.. 이벤트도 씹히기 일수고 영 불안한 모습이었다.

이후 FLEX4에 새로 추가된 컬렉션타입인 AsyncListView의 createPendingItemFunction 이벤트를

이용하여 개발하니 사용자의 이벤트나 현재 보고 있는 페이지의 계산이 훨씬 쉬워졌고

이벤트가 씹힌다거나 하는 현상도 전무하다 싶이 하였다.

사용중인 리모트클래스와 결합하고 콘트롤형태로 다시개발 새 프로젝트에 끼워넣고 있는데

퍼포먼스라던가 자원효율등 어느측면에서도 꽤 생각외로 괜찮다.

일단 dataprovider에 그냥 넣었으면 이미 뻗었을 양의 데이터들을 아주 부드럽고

자연스럽게 뿌려주고 있으니.. 대박 ㅇㅅㅇ

콘트롤을 프레임워크형태의 모음집에 넣어 상용프로그램에 실제 사용중이므로 공개할수는 없고

개발 당시 참고 하였던 관련 사이트들을 링크해본다.

Flex3 에서 사용시에는 Flex4 SDK open source에 있는 AsyncListView 클래스와 관련 클래스들을

그대로 가져가 약간의 변경후 사용하면 별문제 없이 Flex3에서도 동작은 한다.

하지만 그렇게 띄워보고 나서야

아 Flex3와 Flex4의 속도차이가 이런것이었구나 라고 느끼게 되었다는...



개발 참고 사이트

http://www.jamesward.com/2010/10/11/data-paging-in-flex-4/

http://lightsblue.com/examples/flex/PagingRemoteDataWithIList/

http://lightsblue.com/examples/flex/PagingRemoteDataWithIList/srcview/index.html

http://help.adobe.com/en_US/flex/using/WS2c2b6b5d2efbc2ce-17a157741258e87ac50-8000.html



ps. 서버에서는 Spring 컨테이너를 이용

이클립스에서 VisualEditor 플러그인을 설치하여 사용해보았습니다

(http://www.ehecht.com/eclipse_ve/ve.html)

설치는 간단한.. 그저 자신의 이클립스버젼에 맞는 링크를 다운받아

이클립스 설치 폴더에 덮어쓰기로 추가하시면됩니다.

그런후 이클립스에서 새로운 프로젝트를 보면 Visual Class 가 표시됩니다.

간단한 Swing 윈도우 어플을 만들어보았는데

VE가 상당히 깨집니다 ㅠ 영문은 모르겠지만;

콘트롤을 추가할때 AWT, Swing 콘트롤 클래스를 입맛에 맞게 골라 사용할수 있습니다.

AWT 콘트롤로만 구성을 하면 안깨질지도 모르겠지만;;

사용자 삽입 이미지
Visual Class의 편집화면 상단에 윈도우폼이 처음엔 안깨졌는데 ㅠ 깨졌다 안깨졌다를 반복하는;;

뭐 흉하지만 크게 불편하진 않습니다. 어차피 VE가 없을때는 일일이 머릿속에서 상상하며 그렸으니..



일반 자바클래스의 편집화면.. 뭐 항상보는..



자바로 윈도우 어플을 개발하면 참 이로운점중 하나가

JDBC를 이용한 오라클DB연결입니다.

이때는 여타 응용프로그램 개발언어들과는 틀리게 오라클클라이언트가 필요없으니

바로 2-Tier의 DB연결이 가능합니다.

하지만 VE의 이런 노력에도 불구하고

GUI 프로그램은 왠만하면 자바 Swing 프로젝트로 안하시는게 정신건강에 이롭습니다.

그저 집에서도 쓸만한 급할때 오라클클라이언트 없이 DB에 붙기위해 간단한 어플제작할 일이 있어

오랫만에 사용을 해보았지만..

정말 이걸로 프로젝트는 하기싫은..;;

VSmooth 로 이클립스에서 Jar로 Export후 EXE컴파일을 할수 있습니다.

말이 컴파일이지 그저 배포하기 좋은형태로 구성하는정도..

EXE 생성은 별문제가 없습니다.

JDK 의 최소버젼 설정.. 어플의 분류 설정(콘솔인지, 윈도우용인지 서비스인지등)

그리고 저처럼 JDBC등을 사용한다면 별도의 Jar을 Embed 할수도 있습니다.



Generating core library 이후 라이브러리의 인스톨 이후에도

문제가 발생하는경우 RadRails 플러그인 전체 (3개)를 UnInstall 해버리면 정상동작한다.

계속 CPU 100%를 먹으면서 뻗어버리는데 ㅇㅅㅇ;;

RadRails는 이클립스용 루비 플러그인으로 알려져있는데

Aptana에서는 권장 설치 플러그인이면서도 문제가 좀 있는듯 한...

하이튼 이런문제가 없다면 다행이지만 어차피 목적은 HTML, JS를 이용한

Air 프로젝트의 빌드이기 때문에 플러그인 메니저에서

삭제하는 방법으로 해결을 보았다...;;
FLEX의 미려함과 HTML, JS의 자유도있는 코딩을 하는방법이 없을까?

라는 생각에 차기 프로젝트의 언어를 JSP베이스의 웹프로젝트에

FLEX의 CBD를 첨가하는 형태로 해결하려는 찰나

APTANA라는 것을 알게되었습니다. 그래서 구글링을 하며

APTANA를 설치하고 테스트 빌드를 해보며 설치기를 포스팅해봅니다.

사용자 삽입 이미지
APTANA의 로고.. GNU IDE툴입니다. 우왕굳..

처음 설치한 모습은 마치 이클립스를 연상시킵니다.


사용자 삽입 이미지
설치와 동시에 AIR플러그인을 설치합니다.
이클립스에서는 FLEX BUILDER를 정품으로 설치하지 않으면 날짜제한의
플러그인밖에 사용못하지만 APTANA에서는 무료로 플러그인을 사용할수 있네요
AIR 프로젝트에 한해서이지만;;
(첫실행시 Generating core library 라며 프로그레스가
하염없이 진행되는데 한 30분 기다리니 뭔가 잔뜩 다운로드받아놓고
인스톨해야한다며 떴다.. 루비관련된 라이브러리들인데 기본적으로 설치를 권장하는듯)


사용자 삽입 이미지
에어 플러그인 설치중


사용자 삽입 이미지
프로젝트 생성
(일전에 만든 로또 HTML을 AIR로 컴파일하려고 프로젝트 이름이 LOTTO임;)

 
사용자 삽입 이미지
프로젝트 생성

버젼 및 아이콘을 여기서 설정, 추후에도 설정할수 있으니 그냥 Next~
 
사용자 삽입 이미지
프로젝트 생성완료후 컨텐츠타입을 설정하라고 나오는데

더말할필요 없이 UTF-8 로 세팅..

이제 빌드하고 테스트를 하면 될듯한데..................





어떻게 하는거지 ㅇㅅㅇ;?

VB 프로젝트를 진행하던중

디자인에 신경은 써야겠고.. 인터넷에서 버튼콘트롤 하나 받아 사용하려 했더니

기본적인 버그에.. 믿음도 안가고 해서

그냥 직접 새로 만들게 되었습니다.

imgStyle 프로퍼티에 두가지 이미지 형태(흑백과 블루컬러스타일 이미지)를 고를수 있게 해두었고

후킹을 위해 SubClass 를 사용하였습니다.

스타일은 이미지로 일반,마우스오버시 두가지 이미지를 이미지리스트에 등록하고 소스를 수정하면 

되고 기존이미지를 교체해버려도 됩니다.

이미지를 더쪼개어 버튼이 큰 사이즈로 작성될때 깨짐을 방지하고는 싶지만

워낙 바쁜시간 쪼개 만든거라 시간이 없어 이정도만 하려고 합니다.


개인적으로 OCX형태보다 컴파일시 포함되는 형태를 더 선호하기에 소스채로 올립니다.

전 쿨하기에 저작권 그런거 모릅니다.

그냥 막 가따 써도됩니다.


안드로이드용 게임 라이브러리 ROKON

http://code.google.com/p/rokon/downloads/list

설치방법

1. 다운받은 rokon lib러리의 압축을
사용할 프로젝트폴더에서 lib 폴더를 하나 만들고 압축을 해제합니다.

2. 이클립스 workspace 에서 F5 새로고침후 rokon-?-?-?.jar 파일이 보이면
마우스 오른쪽 클릭 - Build path - Add to Build Path


이제 rokon activity 를 상속받아 프로그램을 작성하면 끝..