[Chile] Carmen Reserve Cabernet Sauvignon - 2003 done

Carmen Reserve Cabernet Sauvignon, Maipo Valley
까르멘 리저브 까베르네 소비뇽
국가Chile (칠레)
지역Maipo (마이포)
AppellationMaipo Valley
생산자Vina Carmen (비냐 까르멘) 
빈티지2003
포도품종Cabernet Sauvignon (까베르네 소비뇽) 85% , Syrah/Shiraz (시라/쉬라즈) 10%, Merlot (메를로) 5%
알코올도수14.1 %
가격30,000원 미만
와인 메이커 노트 & 테이스팅 노트
매우 진한 루비색을 띠며, 검은딸기, 까치밥나무등의 과일향과 토스트 향 등의 복잡함이 이채롭다. 비교적 무거운 느낌을 주며, 두껍게 요리한 소고기류, 구운 갈비요리, 토끼고기, 양고기, 고기완자, 진한 맛의 파스타, 치즈 등과 잘 어울린다. 칠레와인 애호가들을 위해 특별히 선택된 와인이다.

정열의 와인, 까르멘(Vina Carmen)
까르멘이라는 브랜드는 창업자 부인의 이름에서 따 온 것이라 한다. 1850년에 창업되어 칠레에서 가장 긴 역사를 가진 몇몇 명문 와이너리의 하나이다. 긴 세월동안 칠레 시장에서만 질 좋은 와인을 공급해 오다 90년대 이르러 국제시장의 진출을 가졌고 칠레 와인의 명성을 세계적으로 넓혀 나갔다.
현재 주인은 리까르도 끌라로(Ricardo Claro). 1987년 유서 깊은 이 와이너리를 인수하고 대대적인 혁신을 가져 역사적 명성에 걸맞는 훌륭한 와이너리로 일으켜 놓았다. 현재 이 와이너리는 마이포, 라펠 까사블랑카 및 꾸리꼬 지역에서 525헥타르의 포도밭을 갖고 있다.
주된 포도원은 안데스 산맥에 자리잡은 알또 하우엘(Alto Jahuel). 이곳은 칠레에서 가장 훌륭한 와인이 난다는 곳이다. 1,400만 리터의 용량과 6,000개에 달하는 오크통을 보유하면서 잘 다듬어진 드넓은 포도밭에서 수확한 포도로 와인을 빚고 있다.
까르멘 와이너리의 와인은 베이스 와인을 비롯해 reserve, wine maker's reserve, gold reserve 등 다양한 시리즈를 선보이고 있다.
(<남국의 와인 - 보르도와인아카데미 시리즈 3>, 최훈)

www.carmen.com

(본 정보는 수입사에서 제공한 정보를 바탕으로 만들어졌습니다. 2007/01)
Wine Spectator rating87
수입사두산주류BG
(총평 :85)
 
김한상 (리뷰 전체보기)
점수 :85
2007.07.20
저렴한 가격대에서 풀바디 와인을 느끼고 싶다면 카르멘 리저브 카쇼를 마셔볼만 하다. 칠레와인은 크게 빈티지를 타지는 않지만, 2003 빈티지는 유독 좋다. 신라호텔에서 운영하는 탑클라우드 레스토랑의 테이블 와인으로 유명한 카르멘 리저브 카쇼 2003은 3만원 이하대에서 풀바디감을 느낄 수 있는 와인이다.

잘 숙성된 오크향과 카베르네 쇼비뇽의 묵직한 풀바디감이 자유롭게 흩어지며 1시간정도 잔브린딩후 즐기기에 적합하다.

두꺼운 고기와 잘 어울리며 다양한 아로마를 느낄 수는 없지만, 육류와 함께하기에 적합한 테이블 와인이다.

MBC에서 인기를 누렸던 드라마인 환상의 커플에서... 한예슬이 "난 카르멘만 마셔"라고 언급하면서 더욱 인기를 누리는 와인이다.

부드러운 치즈와 함께 하면 거친감이 없어져서 괜찮게 마실 수 있다. 3만원 이하에서 풀바디를 느낄 수 있는 와인을 추천해 달라고 한다면 과감하게 추천해줄만한 와인이다.
100~94.1 Perfect94~91.1 Outstanding91~88.1 Excellent88~85.1 Good85~80 Average

권홍식 와인컨설턴트. <광주금수장호텔> 소믈리에
백승헌 와인애호가. 네이버 <와인카페> 회원
오호진 와인애호가. 네이버 <와인카페> 회원
이진백 <와인 앤 더 시티> 저자. 싸이월드 <와인과 사람> 운영진
한성희 <알리고떼> 소믈리에
Wine Review 와인전문 월간잡지 <와인리뷰>
김한상 와인애호가. 네이버 <와인카페> 회원(케리상)
서주완 와인컨설턴트. 싸이월드 <와인과 사람> 운영진
유병호 <르꺄뱅> 대표. 한국국제소믈리에협회 부회장
한  나 <와인스토리> 소믈리에

by 돌쇠 | 2007/08/24 14:44 | My Wine History.. | 트랙백 | 덧글(0)

보르도와인, 다섯 개의 성좌

저녁 시간을 위한 부드러운 선택
보르도와인, 다섯 개의 성좌

 

 

 

선술집에 모여 폭음으로 스트레스를 풀던 넥타이 부대가 부드럽고 유쾌한 담론을 즐기는 와인바로 모여들고, 독일식 수제 맥주나 스타벅스 커피 한잔으로 여유와 낭만을 즐겨왔던 캐리어우먼들은 와인 한잔으로 새로운 스타일 연출을 시도한다. 저녁에 즐길 와인을 구입하기 위해 쇼핑 나온 부부, 와인을 품에 안고 귀가 하는 남편과 맛있는 치즈를 준비하고 기다리는 아내. 이 모두는 와인이 대중화 되면서 변한 퇴근 후의 풍경이다. 부드러운 변화를 시작하고 시작하려는 사람들을 위한 오늘 저녁 추천 메뉴, 보르도 와인의 다섯 최고봉을 소개한다.

 

 

photo01 나폴레옹 3세는 1855년 파리 만국박람회를 통해 세계에 보르도 와인의 우수성을 알리고자 보르도 와인의 등급을 매기도록 명령했다. 이 명령에 따라 보르도 메도크 지방의 60여 곳과 그라브 지방의 와인이 1등급부터 5등급까지 분류되어 그랑 크뤼 Grand Cru로 선정되었고, 이 중에서도 샤토 라피트 로실드, 샤토 라투르, 샤토 마고, 샤토 오브리옹의 네 곳은 프리미에 크뤼 Premiers Crus라는 최고의 영애를 부여받았다. 보르도 와인의 최고 자리는 이후 118년간이네 곳만을 위한 성역이었으나, 1973년 2등급 와인이던 샤토 무통 로실드가 1등급으로 격상되면서 오늘날 ‘보르도 다섯 개의 최고봉’이라 불리는 전설이 완성된다.

1. 최고의 자리는 하나, 샤토 라피트 로실드 Chaeau Lafite Rothschild
샤토 라피트 로실드는 바롱 에리크 드 로실드Baron Eric de Rothschild가 소유하고 있는 프랑스 그랑 크뤼의 1등급 와인으로, 프랑스 메도크 지방에서 가장 많이 알려진 와이너리 중의 하나인포이약 Pouillac 지역 북부에 위치하고 있다. 라피트는 루비색을 띠며 미네랄, 꽃, 까치밥나무열매가 어우러진 향기를 풍기는 것이 특징인데, 메도크의 그랑 크뤼 중에서 가장 매혹적이면서도 가장 이해하기 어려운 와인으로 일컬어지고 있다. 라피트 로실드로 명명된 와인 중에서도 1858·1864·1865·1870·1875년산은 전설의 와인으로 평가되고 있으며, 1999년 빈티지의 라피트 로실드는 과일 향과 오크의 섬세한 밸런스에 의해 깊은 맛과 복합적인 특성이 잘 나타난 것으로 평가받고 있다. 2004년 11월에 한국을 방문한 샤토 라피트 로실드의 사장 크리스토프 살랭 Christophe Salin은 오늘날의 라피트에 대해 다음과 같이 평가한 바 있다. “라피트는 빈티지별로 큰 굴곡이 없는 보수적 경향이 짙은 와인이라 말하고 싶다. 또한 오래된 느낌의 변함없는 레이블은 품질의 일관성을 증명하는데, 이것이 오늘날 와인 애호가들을 매혹시키는 라피트 매력이 아니겠는가?”

2. 깊고 풍부한 남성적 미의 세계, 샤토 라투르 Chaeau Latour
샤토 라투르는 샤토 라피트 로실드와 함께 보르도에서도 가장 좋은 포도주를 생산하는 마을로 널리 알려진 포이약에서 생산된다. 보편적으로 표면에 윤기가 있는 강렬하고 짙은 루비색의 라투르는 무화과나 말린 자두 향이 나고 오래도록 입 안에 맴도는 뒷맛이 인상적이다. 18세기 초에 샤토 라투르는 전 세계, 특히 영국과 유럽과 북유럽 시장에서 좋은 평판을 얻기 시작하여 19세기에 들어서면서 그 가치를 확립했으며, 19세기 말에 이르러 최고의 명성을 얻었다. 현존하는 샤토는 이 황금기, 즉 1862년에서 1864년 사이의 것을 최고로 친다. 일반적으로 샤토 라투르는 남성적 색깔이 짙다는 평가를 받고 있다. 흔히 강건하고 우직한 요새의 돌탑으로 표현되는 샤토 라투르의 이미지는 생산지의 지리적, 역사적 여건에서부터 유래되었다. 샤토 라투르를 생산하는 포도원에는 주변의 다른 샤토들과는 달리 원래부터 있던 성곽의 일부분이 그대로 남아 있는데, 이것은 강가에 위치한 보르도의 지리적 특성상 해적이 자주 출몰하여 이를 방어하기 위해 지롱드 Gironde 강가에 축조되었던 성곽의 일부인 망루가 아직 남아 있는 것이다. 이는 이 포도원에서 생산되는 와인의 라벨에도 똑같이 그려져 있으며, 포도원 이름으로도 사용하고 있다.

3. 섬세하고 우아한 여신의 향기, 샤토 마고 Chaeau Margaux
마고 지역은 세계 최고의 샤토가 밀집되어 있는 지역으로, 샤토 마고는 이 마고 마을에서도 단 하나밖에 없는 특1등급 와인이다. 샤토 라투르가 야성적이고 남성적인 데 반해, 샤토 마고는 고유의 그윽한 부드러움과 섬세한 우아함으로 메도크 와인 중에서도 가장 여성스럽다는 평가를 받는다. 보르도 와인 중에서 가장 향기롭고 우아한 와인으로 평가 되는 만큼 씹힐 듯한 타닌 tannin과 부드럽고 정교한 맛은 단연 일품. 적절히 보관하면 오랫동안 숙성시킬 수 있는 것이 특징인 샤토 마고는 1970년대 이전에는 여성적인 특성이 부각되었지만, 샤토 마고의 르네상스 시대라 불리는 1970년대 이후에는 파워풀한 남성적인 느낌이 부각되기도 했다. 그러나 마고의 전통이 ‘여신의 향기’인 만큼, 최고로 손꼽히는 마고는 풍부한 아로마 향에 카시스 향, 바닐라 향이 느껴지는 봄꽃 향취가 강한 1988년산이다. 이와 함께 타닌과 스모키 오크 아로마 향이 강한 1995년산 역시 최고로 평가받고 있다. 아름다운 여신은 한 사람만의 소유는 될 수 없는 것인지, 샤토 마고는 소유권이 수많은 사람들의 손을 거치며 합병과 홀로 서기를 반복하는 동안 뚜렷한 발전기가 없었다. 그러나 2003년 초에 단독 경영 체제로 안정기를 찾으면서 질적인 향상의 새로운 전환기를 맞이한 만큼 근래에 가장 기대되는 명품 중 하나라 할 수 있다.
 
photo01 4. 최고를 향한 집념의 산실, 샤토 무통 로실드 Chaeau Mouton Rothschild
보르도 메도크 포이약의 188에이커의 작은 포도밭은 해마다 전 세계에서 몰려든 수천 명의 방문객들로 문전성시를 이룬다. 이들의 방문 목적은 오직 블랙에 가까울 만큼 짙고 강렬하며, 블랙베리와 카시스, 모카와 체리 맛에 미네랄과 오크 향이 은은하게 느껴지는 최고의 와인,샤토 무통 로실드를 즐기기 위해서다. 1920년대 초반부터 2등급 와인으로 평가받던 무통 로실드가 1973년 마침내 1등급 반열에 오를 수 있었던 배경에는 바롱 필리페 드 로실드Baron Philippe de Rothschild가 있다.그는 무통 로실드의 질적인 향상과 더불어 2등급이라는 이미지를 불식하고 쇄신시켜야 한다고 생각했고, 이는 곧 최고의 와인병 레이블의 완성으로 이어진다. 맛에 대한 질적인 향상을 거듭하던 1945년부터 그는 파블로 피카소, 마르크 샤갈, 살바도르 달리, 후안 미로 등 세계적 화가들에게 레이블 디자인을 의뢰했다. 화가는 와인, 와인을 마시는 즐거움, 양(‘무통’은 프랑스어로 양 羊을 의미한다)을 주제로 자유롭게 작업하고, 돈 대신 자신의 레이블이 붙는 해와 또 다른 해의 샤토 무통 로실드를 받았다. 이러한 거래를 거부한 화가는 아직 없었으며, 오늘날 이 ‘와인병 위의 미술관’ 마케팅은 성공을 거두어 무통 로실드가 최고의 자리를 유지하는 또 하나의 중요한 요소가 되고 있다.

5. 신과 인간의 합작품, 샤토 오브리옹 Chaeau Haut-Brion
보르도 명성의 역사에서 그라브를 빛낸 장본인은 다름 아닌 샤토 오브리옹이다. 루비색으로 맑게 빛나는 색조와 바닐라 향, 블랙체리, 타닌의 오묘한 조화가 빚어내는 진하고 부드러운 맛의 오브리옹. 흔히들 와인의 맛을 결정하는 세 가지 요소를 얘기할 때 지형과 토양, 포도 품종, 사람의 정성과 기술을 꼽는다. 오브리옹의 지형과 토양은 볼록렌즈처럼 솟아 있는데, 지질학적으로 풍화와 침식 작용을 거치며 형성된 것이다. 경사진 비탈면은 포도를 익게 하는 일조량에 영향을 미치며, 토질은 배수가 잘되고 뿌리가 물을 찾아 쉽게 뻗어 나가게 한다. 일찍이 신의 혜택을 이해한 주민들은 이곳에 포도나무를 심기 시작했고, 포도나무 하나하나에 지극한 정성을 기울이며 포도를 재배했다. 철저하게 만들어진 포도밭 지도를 통해 같은 지역이라도 높이나 성분의 차이를 구별하여 관리하고 수확하기를 500년. 신이 준 혜택과 인간의 노력으로 탄생한 오브리옹이 오늘날 최고의 자리를 차지하는 것은 너무나 당연하다.
 



와인 초보자를 위한 보르도 와인 선택 기준, 6 AOC

AOC Appellation d'Origine Controlee는 프랑스에서 농산품과 식료품 분야의 명칭을 법규에 의해 통제하는 체계, 생산 구역, 품종, 재배 방법, 생산 방식 등의 요건에 관해 프랑스 농산부령으로 승인 절차가 규정되어 있는 원산지 명칭이다.

보르도 Bordeaux와 보르도 쉬페뢰르 Boredeaux Superieur AOC
보르도 전 지역에서 생산되는 레드 와인으로 토양과 품종, 미세 기후 등에 따라 종류가 다양하다. 보르도 쉬페뢰르는 보르도 와인 중에서도 각 지역이나 마을명 AOCb를 통과하지 않은 지역의 와인 중 보르도 AOC보다 훨씬 엄격한 규체를 거쳐 승인된 와인이다.

코트 Rde Cotes AOC
코트 Cotes의 의미는 ‘비탈진 언덕’으로, 이 지역은 주로 지롱드 강과 도르도뉴 강의 오른쪽 언덕을 끼고 있는 기복이 심한 구릉지대에 있다. 주로 남쪽 또는 남서쪽에 포도밭이 위치한다.

메도크 Medoc와 그라브 Graves AOC
8개 지역을 포괄하는 메도크는 ‘중간에 위치한 땅’이란 의미로, 대서양과 지롱드 강 사이에 위치한다. 메도크 와인은 입 안에서 느껴지는 보디와 짜임새가 있는 최고급 레드 와인을 생산한다. 그라브는 AOC 2개 지역이 명칭을 사용하고 있으나, 그라브 지역의 고급 레드 와인은 북부의 페삭 레오냥 Pessac-Leognan 마을에서 생산된다. 그러나 이곳은 그라브가 아닌 독자적인 AOC 명칭을 사용하고 있다.

리브르네 Libournais 생테밀리옹 Saint-Emiilion AOC
6개 지역 포도밭은 중세 도시인 생테밀리옹 마을을 중심으로 형성되어 있다. 와인은 메를로 품종이 주를 이루며, 아름다운 색깔과 풍요로운 부케, 그리고 비단같이 부드러운 맛이 특징이다. 포메롤 Pomerol AOC 2개 지역은 리브르네 시 입구의 고원에 자리하고 있다. 메를로 품종을 주로 사용하는 이 지역의 와인은 진한 밀도감, 붉은 과일과 송로버섯 향, 그리고 비로드처럼 부드럽고 독특한 맛을 지녔다.

드라이 화이트 와인 Dry White Wine AOC
단맛이 없는 이 와인은 조개, 굴, 생선 등의 해산물 요리에 어울리며, 식전주 aperitif로도 적합하다. 대표적인 산지는 그라브, 앙트르 되메르 Entre-Deux-Mers, 코트 드 블라예 Cotes de Blaye.

스위트 화이트 와인 Sweet White Wine AOC
스위트 화이트 와인을 생산하는 지역은 소테른 Sauternes과 바삭 Barsac. 구운 향과 감굴 향에 벌꿀 맛이 감미로움을 선사한다.

 

 

by 돌쇠 | 2007/08/08 12:47 | Wine | 트랙백 | 덧글(0)

솔라리스에서 GC 로그 이상현상 문의. -- From JavaService.net

제목 : 솔라리스에서 GC 로그 이상현상 문의.
글쓴이: 김기호(parankiho) 2007/05/10 11:50:06 조회수:427 줄수:116 
모 사이트에 WAS 관련 지원중 발생한 문제입니다.

제가 솔라리스 JVM을 한번도 사용해 본적이 없어서 문의 드립니다.
아래 로그를 보시면 시작하자마자 Full GC 이고
계속해서 Full GC 라고 GC Log에 찍힙니다.
(아래 로그는 일부이지만 처음부터 끝까지 아래와 동일하다고 보시면 됩니다.)

하지만 보시다시피 Old, 즉 Tenured Generation 의 사용량은 거의 없습니다.(10% 미만)
자세히 보면, Old나 New 영역이 조금씩 증가하기만 하는데도 무조건 Full GC 라고 기록이 됩니다.
JVM 셋팅은 Incremental GC 등의 옵션을 사용한것도 아니고 default 입니다.

Heap 의 초기값을 1GB로 잡았으니, 기본 설정대로
New 에 300정도 Old 에 700 정도가 할당이 되어서 시작하는데
왜 Full GC 라고 찍히는지 이해가 가질 않는 군요.
(메모리 크기에 비해 시간이 0.3초 정도인걸로 봐서는 정말 Full GC 인듯 한데..)

perm size 의 경우는 확인결과 32m 이상 늘어나지 않는걸 확인했습니다만..

게다가 HP 나 IBM 처럼 상세한 GC 내역을 보여주는 옵션(HP의 경우 -Xverbosegc:file)도 없는 듯 합니다.

마지막으로 WAS 재기동시 HP 의 경우는 GCLog가 프로세스 아이디에 따라 새로 생성되는데
솔라리스의 경우 기존 GCLog를 덮어써버리는군요(뒤에 추가되는것도 아니고)

 

정리하자면

1. Full GC 상황이 아닌데 Full GC 라고 보여진다. 혹시 솔라리스의 기본 GC 정책의 특별함이 있는지?
아니면 어떤 이유로 Full GC 가 발생하는건지

2. 솔라리스 JVM 에서 상세한 GC Log 를 찍는 옵션이 있는지.
있다면 무었인지

3. WAS 재기동시(즉, JVM의 재실행) 기존 GC Log 를 덮어쓰지 않는 방법이 있는지.

입니다.

많은 초/중/고수분들의 도움 부탁드립니다.....

=========================================================
Solaris 10
jdk : 1.4.2_11 (64bit)
was : jeus 4.2.2.3

jvm memory option : -Xms1024 -Xmx1024 -XX:PermSize=32m -XX:MaxPermSize=64m

==========================================================

0.000: [Full GC  {Heap before GC invocations=0:
Heap
 def new generation   total 339264K, used 25335K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,   7% used [0xffffffff31c00000, 0xffffffff334bdf50, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 0K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   0% used [0xffffffff47150000, 0xffffffff47150000, 0xffffffff47150200, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 9230K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  14% used [0xffffffff71c00000, 0xffffffff72503820, 0xffffffff72503a00, 0xffffffff75c00000)
0.000: [Tenured: 0K->3715K(699072K), 0.1251362 secs] 25335K->3715K(1038336K), [Perm : 9230K->9230K(65536K)] Heap after GC invocations=1:
Heap
 def new generation   total 339264K, used 0K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,   0% used [0xffffffff31c00000, 0xffffffff31c00000, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 3715K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   0% used [0xffffffff47150000, 0xffffffff474f0c80, 0xffffffff474f0e00, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 9230K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  14% used [0xffffffff71c00000, 0xffffffff72503820, 0xffffffff72503a00, 0xffffffff75c00000)
} , 0.1253746 secs]
4.257: [Full GC  {Heap before GC invocations=1:
Heap
 def new generation   total 339264K, used 78520K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,  23% used [0xffffffff31c00000, 0xffffffff368ae0b0, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 3715K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   0% used [0xffffffff47150000, 0xffffffff474f0c80, 0xffffffff474f0e00, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 18388K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  28% used [0xffffffff71c00000, 0xffffffff72df5268, 0xffffffff72df5400, 0xffffffff75c00000)
4.257: [Tenured: 3715K->14119K(699072K), 0.2477265 secs] 82235K->14119K(1038336K), [Perm : 18388K->18388K(65536K)] Heap after GC invocations=2:
Heap
 def new generation   total 339264K, used 0K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,   0% used [0xffffffff31c00000, 0xffffffff31c00000, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 14119K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   2% used [0xffffffff47150000, 0xffffffff47f19ec8, 0xffffffff47f1a000, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 18388K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  28% used [0xffffffff71c00000, 0xffffffff72df5268, 0xffffffff72df5400, 0xffffffff75c00000)
} , 0.2479585 secs]
64.509: [Full GC  {Heap before GC invocations=2:
Heap
 def new generation   total 339264K, used 3455K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,   1% used [0xffffffff31c00000, 0xffffffff31f5fe20, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 14119K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   2% used [0xffffffff47150000, 0xffffffff47f19ec8, 0xffffffff47f1a000, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 18514K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  28% used [0xffffffff71c00000, 0xffffffff72e14a48, 0xffffffff72e14c00, 0xffffffff75c00000)
64.510: [Tenured: 14119K->14201K(699072K), 0.1542504 secs] 17575K->14201K(1038336K), [Perm : 18514K->18514K(65536K)] Heap after GC invocations=3:
Heap
 def new generation   total 339264K, used 0K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,   0% used [0xffffffff31c00000, 0xffffffff31c00000, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 14201K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   2% used [0xffffffff47150000, 0xffffffff47f2e608, 0xffffffff47f2e800, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 18514K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  28% used [0xffffffff71c00000, 0xffffffff72e14a48, 0xffffffff72e14c00, 0xffffffff75c00000)
} , 0.1544700 secs]

==============================
From parankiho
MailTo : parankiho@naver.com
==============================
 
제목 : Re: 설명할 내용은 많은데, 정리가 잘 안되네요.
글쓴이: 벌레사냥꾼(guest) 2007/05/11 13:00:21 조회수:285 줄수:121 

결론적으로 말씀드리면, GC튜닝이 필요한 상황입니다.

GC가 발생하는 기준은 여러가지가 있습니다.

Minor GC같은 경우는 eden영역이 100%인 경우이고 Full GC인 경우는 좀 복잡합니다.

김기호님이 생각하시는 Full GC는 GC로그상에서 Tenured GC라고 출력되는 경우입니다.

즉 Tenured영역(old)에 대해 GC가 필요하다고 판단되는 경우 발생하는 GC입니다.

로그에서 Full GC라고 찍힌 것은 GC가 전체 영역에 대해 발생했다는 것이지 Old영역이 부족해서 Old영역에 대해 수행했다는 것이 아닙니다.

원인은 여러가지 이기때문에 분석을 좀더 해야겠지만, System.gc()호출이라든지, GC파라미터에 의해 GC가 구동된 것이 대부분입니다.

제가 얼뜻보기에는, s영역이 작은 것이 원인인듯 싶습니다.


그럼, GC튜닝은 어떻게 하느냐...

다를 GC라면 튜닝에 상당한 노하우가 필요하겠지만, Default GC라면 생각보다 쉽습니다.

Default GC의 원리는 생략하도록 하겠습니다.


튜닝의 포인트는 다음과 같습니다.

WAS와 프레임워크와 같이 상시적으로 유지되는 객체는 Old영역에, 서비스(업무) 인스턴스는 New영역에 배치시킴으로써

Minor GC만 발생시킴으로써 Long Pause를 없애고, GC의 Old영역 Scan작업을 없앰으로써 Overhead를 제거한다.

사실 원래 young/old의 설계 개념에 최대한 충실한 것 뿐이지요.


1. old 영역의 크기를 정합니다.

old는 위에서 정의한 상시적으로 유지되는 객체의 크기를 추정해서 해당 대비 4배 정도를 잡습니다.

Tenured영역의 50%를 넘어설 때, 첫 Tenured GC가 발생합니다. 튜닝이 제대로 되면 40%에서 유지시킬 수 있습니다.


2. new에서 old로 넘어가기 위한 threadhold를 증가 시킵니다.

정확한 파라미터 명칭은 기억이 안납니다.

new영역(young영역이라고도 하죠)은 eden과 survivor영역(s1, s2영역으로 다시 구분)으로 구성되는데, 최초 객체 생성시 eden에 생성이 됩니다.

eden영역이 꽉차면, minor gc가 발생하고 살아남은 객체들은 survivor영역(s1으로 가정하겠습니다.)으로 이동합니다.

다시 eden영역이 꽉차면, minor gc가 발생하고 eden영역에서 살아남은 객체와 s1에서 살아남은 객체가 s2영역으로 이동합니다.

다시 eden영역이 꽉차면, minor gc가 발생하고 eden영역에서 살아남은 객체와 s2에서 살아남은 객체가 s1으로 이동하죠

즉, 영원히 살아남는 객체는

eden->s1->s2->s1->s2->s1->s2->.......-> old

의 순으로 이동합니다.

survivor영역에서 old로 언제 이동시키는가?

이 결정에 대해 Default GC는 두가지 파라미터를 제공합니다.

s1과 s2의 이동횟수 쓰레스홀드값(기본 31)과 s1영역의 사용량의 쓰레스 홀드(기본값 기억이 안나네요)입니다.

이 파라미터를 사용해서 eden영역과 s1 영역의 크기는 다음과 같이 예측 가능합니다.

이동횟수를 1회로 잡고 eden영역와 s1영역을 동일하게 잡습니다.

old영역은 충분히 커야합니다.

이후 부하를 가해 변화량을 측정합니다.

eden에서 살아남은 객체가 s1으로 가기 때문에

gc후 살아남은 s1의 메모리 크기는 minor gc시 객체의 생존율입니다.

이동횟수가 1이기 때문에 minor gc발생후, s1영역에서 old로 바로 진입히기 때문에 old영역의 증가율이 s1에서 생존율입니다.

각각

p1, p2라고 하면

메모리 추이는 다음과 같은 것입니다.

p1*x
p1*x + p2*p1*x
p1*x + p2*p1*x + p2*p2*p1*x
.
.
p1*p2*x + p2*p1*x + ....p2^n*p1*x

n이 무한대로 가면 p1x(1-p2)입니다.

x는 eden영역의 크기이고, p1*x*(1-p2)는 s1, s2의 크기입니다.

p1과 p2는 위에서 설명한 방법으로 구한 값들중에 가장 큰값을 적용시키고 만일의 경에에 대비해 20%정도 더 확보합니다.

이로써, eden, survivor, old영역의 크기를 구했고 실제 파라미터를 적용하면 됩니다.

위의 값을 정확히 구해고, 이동횟수를 충분히 크게(예를 들어 1024정도?) 잡으면, 1024회의 minor GC를 거치고 살아남아야 old영역에 들어가게 되고, s영역이 부족해서 old영역으로 들어가지는 않습니다.

예전 튜닝한 후, old영역을 살펴보면

   ********************
  *
 *
 *
*

같은 그래프가 그려져야 합니다.

그리고, 부하를 24시간 가한 환경에서 Tunured, FullGC는 발생해서는 안되고요.

향후 시스템 증설에 대비해 여유 공간을 확보하시면 됩니다.

다른 GC에 비해 TPS는 떨어지지만 튜닝하기 쉬워서 저도 Default GC를 선호하긴합니다만, BMT같은 경우는 어쩔수 없이 삽질하고 있습니다.

글로 설명하기 상당히 어려워서 내용이 잘 전달되었는지 잘 모르겠네요.


 
제목 : Re: 설명할 내용은 많은데, 정리가 잘 안되네요.
글쓴이: 김기호(parankiho) 2007/05/11 13:36:38 조회수:266 줄수:126 
로그에서 Full GC라고 찍힌 것은 GC가 전체 영역에 대해 발생했다는 것이지 Old영역이 부족해서 Old영역에 대해 수행했다는 것이 아닙니다.

원인은 여러가지 이기때문에 분석을 좀더 해야겠지만, System.gc()호출이라든지, GC파라미터에 의해 GC가 구동된 것이 대부분입니다.

제가 얼뜻보기에는, s영역이 작은 것이 원인인듯 싶습니다.

--->>>>>

우선 친절한 답변에 감사드립니다..

new 에서 s1이나 s2로의 이동없이 계속 Full GC라고 발생하는 부분에 대해 이상하다고 생각했었는데
결국엔 제가 가지고 있던 Full GC에 대한 개념이 약간 잘못된 듯 하군요.

Old 영역에 대한 GC만이 Full GC라고 생각했는데... 흠..


제가 무지해서 답변해주신 내용과 매칭이 잘 되지 않는데
귀찮으시더라도 좀 더 자세히 알려주셨으면 합니다.

-----------------------------------------
1. old 영역의 크기를 정합니다.

old는 위에서 정의한 상시적으로 유지되는 객체의 크기를 추정해서 해당 대비 4배 정도를 잡습니다.

Tenured영역의 50%를 넘어설 때, 첫 Tenured GC가 발생합니다. 튜닝이 제대로 되면 40%에서 유지시킬 수 있습니다.
-----------------------------------------
로그를 보시면 아시겠지만 Tenured 즉, Old 영역의 사용량이 5%도 넘지 않으면서 Tenured GC 가 발생을 합니다.
위에 첨부한 로그는 처음부분이긴 합니다만. 저런 형태로 new 부분만 20-30%로 왔다갔다합니다.


------------------------------------------
2. new에서 old로 넘어가기 위한 threadhold를 증가 시킵니다.

정확한 파라미터 명칭은 기억이 안납니다.

new영역(young영역이라고도 하죠)은 eden과 survivor영역(s1, s2영역으로 다시 구분)으로 구성되는데, 최초 객체 생성시 eden에 생성이 됩니다.

eden영역이 꽉차면, minor gc가 발생하고 살아남은 객체들은 survivor영역(s1으로 가정하겠습니다.)으로 이동합니다.

--------------------------------------------

eden 영역이 꽉차지 않는다면(또는 일정량-50%정도 이하인경우) minor gc 역시 발생하지 말아야 하는걸로 알고 있습니다.
또한 로그에서와 같이 eden 이 50%는 고사하고 20% 수준임에도 발생하는게 너무 이상합니다.

- 특정한 옵션을 부여하지 않은 default gc 알고리즘이라는게 중요합니다.

 

가장 이상하게 생각하는 부분의 로그를 보면.
(원문의 로그 중, 마지막 부분입니다.)


4.257: [Full GC  {Heap before GC invocations=1:                              ----->>>>>>(1번)
Heap
 def new generation   total 339264K, used 78520K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,  23% used [0xffffffff31c00000, 0xffffffff368ae0b0, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 3715K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   0% used [0xffffffff47150000, 0xffffffff474f0c80, 0xffffffff474f0e00, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 18388K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  28% used [0xffffffff71c00000, 0xffffffff72df5268, 0xffffffff72df5400, 0xffffffff75c00000)
4.257: [Tenured: 3715K->14119K(699072K), 0.2477265 secs] 82235K->14119K(1038336K), [Perm : 18388K->18388K(65536K)] Heap after GC invocations=2:
Heap
 def new generation   total 339264K, used 0K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,   0% used [0xffffffff31c00000, 0xffffffff31c00000, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 14119K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   2% used [0xffffffff47150000, 0xffffffff47f19ec8, 0xffffffff47f1a000, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 18388K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  28% used [0xffffffff71c00000, 0xffffffff72df5268, 0xffffffff72df5400, 0xffffffff75c00000)
} , 0.2479585 secs]                                                                                                          --->>>>>>(2번)
64.509: [Full GC  {Heap before GC invocations=2:                                                                             --->>>>>>(3번)
Heap
 def new generation   total 339264K, used 3455K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,   1% used [0xffffffff31c00000, 0xffffffff31f5fe20, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 14119K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   2% used [0xffffffff47150000, 0xffffffff47f19ec8, 0xffffffff47f1a000, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 18514K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  28% used [0xffffffff71c00000, 0xffffffff72e14a48, 0xffffffff72e14c00, 0xffffffff75c00000)
64.510: [Tenured: 14119K->14201K(699072K), 0.1542504 secs] 17575K->14201K(1038336K), [Perm : 18514K->18514K(65536K)] Heap after GC invocations=3:
Heap
 def new generation   total 339264K, used 0K [0xffffffff31c00000, 0xffffffff47150000, 0xffffffff47150000)
  eden space 329024K,   0% used [0xffffffff31c00000, 0xffffffff31c00000, 0xffffffff45d50000)
  from space 10240K,   0% used [0xffffffff45d50000, 0xffffffff45d50000, 0xffffffff46750000)
  to   space 10240K,   0% used [0xffffffff46750000, 0xffffffff46750000, 0xffffffff47150000)
 tenured generation   total 699072K, used 14201K [0xffffffff47150000, 0xffffffff71c00000, 0xffffffff71c00000)
   the space 699072K,   2% used [0xffffffff47150000, 0xffffffff47f2e608, 0xffffffff47f2e800, 0xffffffff71c00000)
 compacting perm gen  total 65536K, used 18514K [0xffffffff71c00000, 0xffffffff75c00000, 0xffffffff75c00000)
   the space 65536K,  28% used [0xffffffff71c00000, 0xffffffff72e14a48, 0xffffffff72e14c00, 0xffffffff75c00000)
} , 0.1544700 secs]


4.257 초에 어떤 이유에선가 Full GC 가 발생했습니다.(1번참조)
그 결과로 (2번)에서 Full GC 가 끝나면서 eden 0%, s1 0%, s2 0%, tenured 2% 인 상태로 Full GC가 끝났습니다.
(Perm 은 제외하고 설명하겠습니다.)
그럼 64.509초(3번)에서 Full GC 가 발생한다는건 적어도 어떤 변화는 있어야 한다고 생각하는데.
(2번) 상태와의 차이란 eden 영역이 1%로 증가했다는 것 밖에 없습니다.

즉, 고작 eden 1%를 지우기 위해서
64.510: [Tenured: 14119K->14201K(699072K), 0.1542504 secs] 17575K->14201K(1038336K), [Perm : 18514K->18514K(65536K)]
이 발생한다는게 아직도 이해가 가질 않네요. tenured 영역은 699072K 가량이 미리 생성되어 있는데
고작 82K(14119K->14201K)가 더 tenured 영역에 들어가기 위해 Tenured GC 가 발생한다??

제가 gc 로그를 잘못 읽고 있는건지..
gc 에 대한 개념이 없는건지... 복잡하네요.

다만 s1, s2 영역이 계속해서 0%인걸로 봐서는
답변주신대로 s1, s2영역의 크기가 너무 작어서 eden 에서 살아남은 객체들이 이동하지 못하는 것 같습니다.
(이부분은 정확히 모르겠네요. 일단 사이즈를 늘려서 모니터링 해보는 수 밖에 없을 듯 싶습니다.)

 

또한 Tenured GC 가 발생하는 경우가 Tenured 가 부족한 경우 이외에 또 어떤 경우가 있나요?

염치불구하고
부디 '많은벌레사냥꾼'님도 도와주시고 또 다른 분들의 도움도 부탁드립니다.
그래도 JVM 튜닝은 이제 왠만큼 한다고 생각했는데.. 역시 갈길이 멉니다..

==============================
From parankiho
MailTo : parankiho@naver.com
==============================
 
제목 : Re: 아마도 System.gc() 가 동작하는 것 같네요.
글쓴이: 너스(guest) 2007/05/14 11:15:11 조회수:312 줄수:49 

1.
로그 상황을 보니, 코드의 어딘가에서 System.gc()를 1분 간격으로 호출하는 것으로 보입니다.

JVM 시작후 4초, 64초 경에 Full GC발생하는 것으로 보아 그런 것 같습니다.
제 짐작이 맞다면 124초, 184초 경에 발생한 로그가 있겠군요.
물론 발생 시간은 조금씩, 한 0.5초씩, 뒤로 밀리겠죠.

아래의 option은 System.gc()를 disable 시킵니다.

 -XX:+DisableExplicitGC

이렇게 해 놓으시고 tuning하시면 되실 것 같습니다.


2.
님께서 보신 로그가 가장 상세한 로그 형태입니다.
각 메모리 영역별 상황을 보여주니까요.

-XX:+PrintTenuringDistribution

이 옵션은 survival space에서 존재하는 객체들의 이동 횟수를 보여주는데,
그다지 큰 도움은 되지 않습니다.


3.
기존 로그를 덮어쓰지 않으려면, WAS 구동 shell script에서 pid로 이름을 받아서 로그를 남기는 방법을
사용하시면 됩니다.
제가 기억을 잘 못하겠는데, $$ 를 사용하는 것 같은데, 죄송합니다만, 님께서 직접 찾아 보시는게...

아니면, WAS에서 제공하는 log를 남기는 방법을 활용하셔야 할 것 같습니다.


+ 추가 사항
1) PermSize와 MaxPermSize는 동일하게 설정하시는게 좋습니다.

2) 그리고, 아무리 튜닝을 잘하셔도 Tenured GC는 발생합니다.
이유는 아무리 enden 영역이 커도 old 영역으로 promotion되는 객체는 존재할 수 밖에 없기때문입니다.
그리고 그 pomotion되는 객체들이 아주 미량이나마 존재하는한 언젠가는 Tenured GC가 발생합니다.
(상세한 설명은 생략합니다.)
그렇게 때문에 JVM의 전체 메모리를 아주 크게 설정하는 게 가장 좋은 답은 아닙니다.

3) 1.4.2라면 jstat (또는 jvmstat) 를 사용하셔서 모니터링하는 것도 권고합니다.
java.sun.com에 가셔서 구하시면됩니다.
JDK 1.5에서는 default로 내장되어 있지만, 1.4.2 는 download 받으셔야 합니다.


도움이 되시기를...

 
제목 : Re: 추가 사항의 반론
글쓴이: 벌레 사냥꾼(guest) 2007/05/15 09:51:59 조회수:234 줄수:36 
"pomotion되는 객체들이 아주 미량이나마 존재하는한 언젠가는 Tenured GC가 발생합니다"

라는 말씀이 제 생각과 다르네요.

물론 포인트는 다릅니다.

저도 eden에서 old영역으로 넘어가는 것을 크기를 늘려서 해결할 수 있다고 생각하지 않습니다.

제가 튜닝한 포인트는 이글 쓰레드 중에 있으니 따로 언급은 하지 않겠습니다.

결과적으로 old가 saturated된후 2시간 부하상황에서 1k의 증가도 없었습니다.

실제로는 며칠동안 운영한 경우와 비슷하다고 생각되고 실제로 현업들이 반응속도가 빨라졌다는 의견을 들었습니다.

실제 tps는 0.2%정도 손실됐습니다만, 평균 gc타임이 0.5미만이었고 gc가 발생하는 빈번도도 4에 한번 정도였습니다.

만일 survivor이동 횟수를 500으로 정할 경우 eden에서 old로 넘어가기까지 약 30분정도 걸립니다.

이 시간동안 유지되는 객체라면 영구히 존재하는 (WAS나 공통 객체같은) 객체일 가능성이 높죠.

물론, 영역의 크기나 다른 파라미터를 조정하지 않으면 다른 요인에 의해 Tenured GC가 발생합니다.

그러나, 다른 요인을 배제하면 단지 영역의 크기와 이동횟수 파라미터만으로 튜닝이 가능합니다.


추가적으로 일정한 시간마다 gc가 발생했다면, rmi 에서 하는 gc일 가능성이 있습니다.

JVM은 객체의 변화에 따라서만 gc가 구동합니다.

아무일도 하지 않는 경우에는 gc가 발생하지 않죠.

그런데, WAS의 경우 타이머를 사용해 특정시간에 gc를 발생시키는 방법이 있습니다.

역시 정확한 옵션은 기억나지 않지만 rmi객체의 gc를 주기적으로 해주는 옵션이 제우스에 있었던 것 같습니다.

jeus.properties나 jeus에 찾아보시면 있을 겁니다.
 
제목 : Re: 어플리케이션 및 운영 상황에 따라서 다릅니다.
글쓴이: 너스(guest) 2007/05/15 10:56:17 조회수:232 줄수:42 

GC에 대하여 많이 알고 계시니, 요점만 씁니다.

제가 언급한 것은 튜닝이 불가능하다는 의미가 아니라,
그 어떤 방법을 써도, 'Old GC가 발생하는 것을 막을 수 없다.' 입니다.

어플리케이션의 특성에 따라서, eden에서 old로 promotion되지 않을 수도 있습니다.
(운좋게) 그런 어플리케이션이 있는 경우도 있습니다만, 일반화시키기는 어렵습니다.
즉, 모든 어플리케이션이 그렇게 동작할 수는 없습니다.

이유는,
1. survivor space의 크기를 넘는 객체들이 생성될 수도 있습니다.
2. 어떤 객체들은 상상외로 길게 long live할 수도 있습니다.

갑자기 부하가 조금 더 걸리는 순간은 이런 경우들이 더 자주 발생할 것입니다.

이런 이유들로 모든 객체가 eden에서 소멸되지 않을 가능성은 충분히 있습니다.

물론, tenuing threshold를 조절하는 것은 매우 좋은 turning 방법입니다만,
GC의 시간을 많이 잡아먹는 Old GC의 발생을 궁극적으로는 막을 수는 없습니다.

결론은,
그 어떤 방법을 써도, 'Old GC가 발생하는 것은 막을 수 없다.' 입니다.
그 발생 빈도를 획기적으로 줄이는 것은 님께서 말씀하신 방법대로 가능합니다.


관련된 의견의 기술적인 배경을 하나 더 말씀드립니다.

동시 사용자가 10명인 시스템과 100명인 시스템의 JVM Heap 메모리 크기의 configuration은 달라져야 합니다.
이유는, 동시 사용자가 많은 시스템은 객첵의 생성량도 많고, minor gc 시의 live한 객체의
수 및 양도 많을 것입니다.
물론 이 경우에 10배로 크게 메모리 구성을 할 필요는 없지만,
10명과 100명의 상황에서는 확실하게 100명의 경우가 메모리를 크게 구성해야 합니다.
(이 부분은 이견이 없으시겠죠?)

님께서 튜닝하신 시스템에서 만일 사용자가 좀 더 증가한다면,
또는 traffic이나 transaction 량이 좀 더 증가한다면,
(즉, user interactive한 시스템인 경우에 heavy한 select query를 처리하거나 하는 등)
그렇게 된다면, tenured 영역으로 이전되는 live한 객체가 발생할 가능성이 있겠죠?
결국은 언젠가는 Old GC가 발생하지 않을까요...


 
제목 : Re: 오랜만에 재미있는 쓰레드가 생겼네요.
글쓴이: 벌레 사냥꾼(guest) 2007/05/15 12:04:22 조회수:248 줄수:51 
서로의 가정이 틀린 것 같습니다.

너스님은 모든 케이스에 대한 고려인 것 같네요. 반대로 저는 웹어플리케이션을 가정했습니다.

저는 기본 모델이 확률 모델입니다.

너스님이 말씀하신 부분

1. survivor space의 크기를 넘는 객체들이 생성될 수도 있습니다.
2. 어떤 객체들은 상상외로 길게 long live할 수도 있습니다.

에서 저는 이렇게 생각합니다.

1. survivor space의 크기를 넘는 객체들이 생성될 가능성은 작다.(survivor영역을 추정하는 방법은 위에서 설명)

2. 상상외로 길게 long live 하는 객체가 발생할 가능성은 작다.

예를 들어 횟수에 대한 쓰레스 홀드는 65536까지 설정가능하고 gc빈번도가 5초, survivor영역의 크기가 충분히 크다면 old영역에 들어가기 위해서는 3.7일이 걸립니다.

3.7일 이상 live하는 객체라면 당연히 old영역에 들어가는 것이 맞지 않을까 생각됩니다.

웹어플리케이션이라면 특히나 data tier는 db를 주로 사용할 테고, 각서비스간의 연계는 session을 이용하는 것이 보통일 것 같은데, 일반 온라인 서비스의 경우 3.7일간 지속되는 task chain이 발생할 수 있을까요?

그 정도라면 batch로 돌리는 것이 맞다고 생각했습니다.


추가적으로 동시 사용자 10명과 100명의 시스템 예는 JVM configuration이 바꿀 필요가 없을 수도 있습니다. 제대로 튜닝이 되어 있다면 보통은 필요가 없습니다.

이유는 현재 논의가 WAS를 가정하고 있기 때문입니다.

WAS에서 보통 queueing 모델을 기본적으로 적용하고 있고, 실제로도 thread queue를 적용하는데 100명이 동시에 접속하더라도 WAS의 max thread가 10인 경우는 10개의 쓰레드만 돌게 됩니다.

물론 시스템 확장시 튜닝을 새로 해야하지 않느냐는 질문이 있을 수 있는데, 튜닝은 application 단, 공통 유틸, 미들웨어, jvm, os와 같은 순으로 상위 layer에서 하위 레이어로 진행합니다.

상위 레이어가 동일하다면 하위단은 변경이 발생하지 않아야 합니다.

마지막에 말씀하신 부분에서 사용자 증가시 was의 max thread제한에 걸리게 되고 그 사용자는 대기 상태에 있게 되기 때문에, 객체 생성량이 증가하지는 않습니다.

실제로도 부하 테스트시 10명부터 시작해서 100까지 증가시키면 tps는 증가하다 saturate되고 이후는 유지됩니다.

또한 메모리 증가 추이도 비슷하게 부하를 아무리 증가 시켜도 saturate됩니다.

그리고, 같은 이유로 부하가 폭발적으로 걸리더라도 메모리는 10개 업무분만 쓰게 됩니다.


현재 개인적으로 java memory관련해서 문서를 만들고 있는데, 기본 모델을 확률 모델로 했습니다.

확률 모델이란게 worst case에 대해서는 고려하지 않다보니 생각이 짧았던 것 같습니다.

현제 WAS를 사용한 application튜닝 사례와 eclipse의 gc튜닝을 예로 포함시켜서 진행하고 있는데, 혹시 특이한 사례가 있다면 알려주시면 감사하겠습니다.

 
제목 : Re: 그렇다면, 힘들게 튜닝하는 과정이 필요 없을 것 같네요.
글쓴이: 너스(guest) 2007/05/15 13:36:47 조회수:234 줄수:63 

이렇게 글로써 진행하는 의견 교환은 상당히 어렵네요.

현실적인 예로써 한번 애기를 해 봅니다.

우선, 님의 생각과 저의 생각이 가장 차이가 나는 부분은,
'Old GC의 발생을 0으로 할 수 있다.'에 대한 견해 차이라고 생각합니다.

저는 '웹 어플리케이션에서도 그런 경우는 거의 없다' 라는 의견이고,
님은 '대부분의 웹 어플리케이션은 그렇게 할 수 있다' 라는 의견이라고 생각합니다.
(맞나요? 이게 아니라면 더 이상의 토론은 의미가 없네요.)


만일 님의 의견이 맞다면,
JVM Heap Size를 최대한 키우는게 가장 좋은 best practice가 될 것으로 저는 생각합니다.

예를 들어, 어떤 웹 어플리케이션을 tuning했는데,
1GB의 Heap 크기에,
eden - 300MB, old - 700MB 정도로 구성하였을 때,
그리고, S0, S1의 크기가 각각 100MB 정도일 때,
Old GC가 발생하지 않는 app 및 운영 상황이라면,

이때, JVM heap 크기를 3-4배로 키워도 문제가 없을 것입니다.
minor gc의 시간은 조금 늘어날 것입니다.
하지만, 통상적으로 minor gc의 시간은 큰 문제가 되지 않습니다.
아마, 3GB의 heap size에서 minor gc의 시간은 평균 1초 이내가 아닐까 하네요.


그렇다면, 굳이 님께서 제시하신 tuning process를 거칠 필요가 없지 않을까 생각합니다.
왜냐면,
jvm heap min, max를 3.6GB 정도로 설정,
(이 크기는 32bit JVM에서 할당 가능한 가장 큰 크기입니다.)
young 영역을 한 1GB 정도,
survival ratio를 1 또는 2 정도로 설정,
(그러면, s0, s1은 각각 대략 200-300M 정도 되겠네요.)
max tenuring threshold를 65535 정도로 설정하면

거의 모든 web app에서는 old gc가 발생하지 않게 되지 않을까요?

왜냐면, web app의 behavior는 거의 유사하고 (님의 가정임)
(여기서, behavior는 memory foot print 및 객체의 생존 시간이 되겠죠)
현실적으로 가능한 가장 큰 survivor space 크기를 부여하고,
충분히 survivor space에서 객체가 머무르게 65535로 횟수 조절도 했으니까요.

정말로 이렇게 된다면,
많은 web app들이 그 동안 고민했던,
old gc 때의 5~10초 이상의 pause time 및 그로 인해 발생되는 문제들이 한방에 해결됩니다.


근데, 그렇지 않을 것 같은게 저의 생각입니다.
그에 대한 이유는 앞의 쓰레드에 설명을 했다고 생각하고요.


* 추가 의견
제가 한 얘기에서,
만일 minor gc 의 시간이 문제라서, 4GB에 가까운 메모리를 할당하는 것은 문제가 있다고 생각하시면,
tuning process를 역으로 해서,
즉, 일단, 최대한 큰 메모리를 부여하고,
s0, s1, old 영역의 메모리 점유율을 관찰한 다음,
(관찰 시간은 1일이면 충분하지 않을까 하네요)
그 점유량에 맞춰서 old, eden, s0, s1 의 크기를 결정하면 되지 않을까 합니다.


 
제목 : Re: 음, 생각해보니 최적화 자체가 현실 상황에서 필요한 것 같네요.
글쓴이: 벌레 사냥꾼(guest) 2007/05/16 10:25:53 조회수:232 줄수:98 
말씀하신 것이 모두 맞습니다. 저도 이론적으로는 그런 결과에 도달했구요.

근데 말씀하신 현실에서는 그렇지 못했습니다.

막상 메모리를 늘려도 실제로는 tps가 더 증가하지도 않고 단지 minor gc 시간만 길어졌습니다.

즉, 튜닝의 효과를 보기 전에 이며 다른 쪽에서 병목이 발생한 것이죠.

3.6G가 풀로 사용할 정도면 이미 cpu나 네트워크같은 쪽에서 병목이 발생해 버리는 거죠..

실제 모니터링 한 결과 시스템 call횟수가 꽤 많았고 wait타임이 길었는 것으로 보아 네트워크 쪽에서 병목이 발생한 것 같습니다.

만일 네트워크가 받혀줬다면, 말씀하신대로 메모리를 가장 크게 잡으면 되었겠지요.

아, 제가 만진 시스템은 8개의 ap서버(1대는 배치 전용)가 있고, 각 서버마다 2개의 container가 있었습니다.

db도 3개로 분리되어 있었구요. 실제 튜닝은 모든 container에 부하를 건 상태에서 하나의 container에 대한 튜닝을 진행했습니다.

추측하기에는 context switching과 같은 각 쓰레드, 프로세서의 경쟁에 의해 시스템 콜이 많아지고 이 때문에 네트워크 대기가 많음에도 쓰레드를 증가 시킬 수 없었던 것 같습니다.

만일, 서버 자원이 빵빵하다면, 말씀하신대로 memory 튜닝은 거의 필요하지 않을 것 같습니다.

그리고, gc튜닝의 목적은 long pause를 없애는 것에 주안점이 맞춰져 있었습니다.

gc튜닝 사례에도 tps의 증가는 3%정도가 최고였던 것같습니다.(기억으로는 parallel을 사용했던 듯)


결과론적으로 최적화 무용론에 도달하게 되네요.(장비를 늘리면 된다?)

아시겠지만 장비를 늘리는 것이 현실에서는 쉽지 않은 문제이고 그렇기 때문에 주어진 환경에서 좀더 좋은 성능을 뽑아내야만 하겠죠

제도 보통 튜닝을 하게 되면 많은 불만이 있습니다.

도대체 장비는 왜 이딴 것 쓰는 거야? 부터 해서 WAS, 서버 숫자, contianer숫자, thread pool갯수, L4셋팅까지

바꿀려고 딴지도 몇번 걸어봤지만, 여러가지 이유(영업, 돈, 정치, 심지어는 다른 개발자의 자존심)로 바꿀 수 있었던 적은 거의 없었습니다.

결국 주어진 환경에서 주어진 일만 하게 되더라구요.

마지막에는 약간 넋두리같이 되어 버렸네요.

그리고, 윗글에서 약간 틀리신 부분이 minor gc가 1초 미만이라는 부분은 전혀 아닙니다.

WAS와 공통 유틸을 올리면 실제 100 메가를 넘는 정도 밖에 안되었습니다.

old영역은 512 메가를 할당했고 전체 2.5기가였으며, 그중 perm이 1기가 정도(사용량은 600메가 정도?) 였습니다.

perm 사이즈를 보시면 아시겠지만 작은 시스템은 절대 아닙니다.

1기가가 new영역이고 survivor ratio가 8이었습니다. gc타임은 평균 0.5초 정도였지만 max 1초 정도였습니다.

아슬아슬하게 1초를 안넘어서 통과했죠.

튜닝하기 전에 3.8g통채로 잡은 경우는 minor gc도 2초 3초였고 FULL gc도 7~8초까지 된 경우도 있었습니다.

무엇보다 그래프를 그리면 gc에 의해 시스템이 불안정해지는 것이 가장 큰 문제였습니다.

그리고 하나더!

32bit에서 4giga 역시 틀린 내용입니다.

sun jdk 1.4.x-32bit 기준으로 2giga limit가 걸려있습니다. 단, 64bit머신에서는 limit가 4giga(32-bit addresss limit)로 올라가는데, jvm과 기타등등(대부분이 gc가 사용하는 공간)에서 쓰는 주소 공간을 빼면 3.8giga 정도 입니다.

또한, os에 따라 limit가 바뀝니다.

기억에는 ms 가 가장 작았던 것(1.6giga) 같은데 만일 주어진 환경이 ms이고 sun인경우라면, 생각보다 충분한 메모리 공간을 확보할 수 없습니다.

즉, 요점은 생각보다 제약사항이 많다는 거죠.^^;


마지막으로 추가의견에 대해서는 완전히 동의합니다.

제가 위에 쓴 글이 old, eden, s영역의 크기를 쉽게 한번에 찾는 방법입니다.

관찰 시간은 부하상황에서 20분 정도면 충분하다고 생각하고요.

단, 부하를 줄 업무 선정에 따라 관찰은 여러번해야 하는 경우도 있습니다.

제 경우는

login만(9시경에 폭발적으로 발생하지 않을까 하는 생각에...)

주요 업무(가장 자주 사용할 업무 10개)

가장 무거운 업무만

이렇게 했고, 계산된 값에서 좀 여유 공간을 더 확보했습니다.(eden영역은 더 확보하면 안되고요. gc time도 증가하고, 계산값이 다 틀려버려지니까)


이정도면, 제가 얘기하고 싶은 내용은 충분히 전달한 듯 싶네요.

내용이 복잡하고 그다지 관심이 없는 분야라 쓰레드가 진행이 될까하는 걱정도 했었는데, 서로 의견 교환이 잘되어서 기쁘네요.

사실 실제 튜닝하러 나가면 제대로 말이 통하는 사람이 거의 없어서, 그냥 고객한테는 어려운 용어 써가면서 얼버무리고

혼자 끙끙대면서 진행하는 경우가 대부분인데, 이런 기회에 풀 수 있어서 기쁘네요.


 
제목 : Re: 아. 감사합니다...
글쓴이: 김기호(parankiho) 2007/05/17 13:44:25 조회수:221 줄수:29 
요새 하도 일이 많아서 막상 글을 올리고도 확인을 못했네요.

여러가지 의견 내주셔서 감사합니다.

--------------
그런데, WAS의 경우 타이머를 사용해 특정시간에 gc를 발생시키는 방법이 있습니다.

역시 정확한 옵션은 기억나지 않지만 rmi객체의 gc를 주기적으로 해주는 옵션이 제우스에 있었던 것 같습니다.

jeus.properties나 jeus에 찾아보시면 있을 겁니다.
-------------

하지만 이부분은 아마 헷갈리신듯 합니다.
rmi gc 같은 경우 jeus 에서는 manager process 에서 발생하며 컨테이너에서는 발생하지 않습니다.
아마 다음 예와 같은 옵션일꺼라 생각됩니다.

-Dsun.rmi.dgc.client.gcInterval=21600000 -Dsun.rmi.dgc.server.gcInterval=21600000 -Djeus.properties.replicate=sun.rmi.dgc


full gc를 지연시킬수는 있어도 완전히 피할 수 없다고 생각합니다만.
max tenuring threshold 수치를 이용하는 방법은 기회가 되면 한번 시도해봐야겠군요.

어쨌거나 세상은 넓고 배울껀 끝이 없네요. ㅎㅎㅎ 감사합니다.


==============================
From parankiho
MailTo : parankiho@naver.com
==============================
 

by 돌쇠 | 2007/08/06 15:35 | Java | 트랙백 | 덧글(0)

jstat 사용법

성능 튜닝시 뭘 먼저 할것인가?
한번쯤은 생각해봐야 하는 내용이다.

1. AS-IS System 분석
   - AS-IS System 을 분석하고 현업과의 Communication 을 통하여 어떤 문제가 발생하고 있는지
     를 파악해야한다.

2. 성능 모니터링
    - 다양한 성능 Factor 를 모니터링 및 수집하여 장애 Point 를 잡아야한다.

3. 장애 분석
    - 장애 Point 라고 파악된 부분에 대하여 현업과 협의를 진행한다.
    - 단순한 수치상의 값으로는 장애라고 판단해서는 안된다.
    - Business Process, Resource 사용율 등등 장애가 아닐수도 있다.

4. Tuning and Test
    - 장애 Point 에 대하여 Tuning 을 진행한다.
    - Tuning 진행 후 테스트를 통하여 Tuning 성과를 검증한다.

5. 성능 모니터링
    - 성능 모니터링 부터 다시 Interation 한다.

6. 기술 이전 및 검수
    - Tuning 관련 History Data 및 기술 이전을 실시한다.


성능 Tuning 시 다양한 방법론이 존재하겠지만 간략하게 정의해 보면
보통 이런 형식일 것이다.

그럼 여기서 중요 Factor 중에 하나는 무엇일까 ?
성능 모니터링이다.
뭘로 할건데?
보통 Stree Tool , APM Tool , SMS Tool 등 고가의 Tool 을 사용하는 경우가 대부분이다.

여기서는 Memory 상태를 추적할 수 있는 공짜 Tool 을 하나 소개하겠다.
Sun JDK, HP JDK 에 포함되어있는 것으로 jstat 라는 것이다.
현재 JVM 의 Heap Memory 상태를 실시간으로 추적하는 매우 효율적인 Tool 이다.

다음은 jstat 에 사용할 수 있는 파라미터들이다.

[ngwas1:/NGI/agreeDomain]jstat
invalid argument count
Usage: jstat -help|-options
       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

Definitions:
  <option>      An option reported by the -options option
  <vmid>        Virtual Machine Identifier. A vmid takes the following form:
                     <lvmid>[@<hostname>[:<port>]]
                Where <lvmid> is the local vm identifier for the target
                Java virtual machine, typically a process id; <hostname> is
                the name of the host running the target Java virtual machine;
                and <port> is the port number for the rmiregistry on the
                target host. See the jvmstat documentation for a more complete
                description of the Virtual Machine Identifier.
  <lines>       Number of samples between header lines.
  <interval>    Sampling interval. The following forms are allowed:
                    <n>["ms"|"s"]
                Where <n> is an integer and the suffix specifies the units as
                milliseconds("ms") or seconds("s"). The default units are "ms".
  <count>       Number of samples to take before terminating.
  -J<flag>      Pass <flag> directly to the runtime system.


위에 있는 <option> 을 보겠다.

[ngwas1:/NGI/wily601]jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-printcompilation


위와같이 여러개의 옵션이 있는데 여기서 우리는 GC 관련 옵션을 선택하여 Heap Memory Area 를 추적해보겠다.

[ngwas1:/NGI/wily601]jstat -gc -h20 6637 3000
위의 명령을 해석해보면...

-gc : GC 되는 것을 보겠다는 의미
-h20 : 아래 데이터를 보면 알겠지만 숫자에 대한 헤더가 있는데 그 헤더를 20 라인마다 찍겠다는 의미이다.
6637 : Process PID 이다. 이건 항상 변하겠죠?
3000 : 시간이다. ms 단위라서 3000 이면 3초마다 한번씩 데이터를 추출하겠다는 얘기다.

위와같이 명령을 실행하면 아래와 같은 내용이 추출되며 각 줄마다 3초에 한번씩 추출된다.
그럼 아래의 데이터를 보는 법을 알려주겠다.
첫번째 파마리터 부터 설명을 붙여주겠다.

SOC : Servivor 0 Area Capacity
S1C : Servivor 1 Area Capacity
SOU : Servior 0 Area Used
S1U : Servivor 1 Area Used
EC : Eden Capacity
EU : Eden Used
OC : Old Capacity (Tenured Capacity)
OU : Old Used (Tenured Used)
PC : Permanent Capacity
PU : Permanent Used
YGC : Young GC Count
YGCT : Young GC Count Time (Young GC 시간이다. 누적시간이므로 아래서 위의 시간을 빼면 Young GC Time 을 알수있다)
FGC : Full GC Count
FGCT : Full GC Count Time
GCT : GC Time (YGCT + FGCT)

어려운가 ?

http://blog.naver.com/salsu0/30000025219  <== 요기를 읽고나서 보면 안어렵다.

그럼 아래 데이터를 한번 분석해 봅시다.

S0 Area 는 34 메가 정도가 할당되었다.
S1 Area 역시 동일하게 할당되었다.
Eden Area 는 72 메가 정도가 할당되었고
Old Area (Tenured Area) 는 700 메가 정도가 할당되었다.
Permanent Area 는 130 메가 정도 할당되었다.

Young GC 가 마지막줄을 봤을때 40 번 실행되었고,
Full GC 는 실행된적이 없다.

Young GC 가 40 번 실행되는 동안 걸린 시간은 7초 정도이며
맨 밑에 세번째 줄과 다음 줄을 비교해봤을때 Young GC 가 일어난 시간은 0.17 초 정도이다.
알다시피 GC 할때는 전혀 일을 하지 않는다.
물론 Default GC Option 일 경우이다. (다음번에는 GC Option 의 종류를 설명하겠다.)

그럼 다들 한번 테스트를 해보기를 바란다.

잼있죠 ?

  S0C        S1C     S0U      S1U      EC           EU            OC           OU            PC         PU        YGC    YGCT FGC    FGCT     GCT  
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 72110.9   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 73802.8   699072.0   86240.1   131072.0 69871.3     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 76141.1   699072.0   86240.1   131072.0 69871.4     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 102379.9  699072.0   86240.1   131072.0 69871.7     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 159719.5  699072.0   86240.1   131072.0 69875.0     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 207689.5  699072.0   86240.1   131072.0 69946.6     39    7.006   0      0.000    7.006
34944.0 34944.0  0.0   17142.6 279616.0 259934.1  699072.0   86240.1   131072.0 69948.0     39    7.006   0      0.000    7.006
34944.0 34944.0 17625.0  0.0   279616.0 50821.6   699072.0   86240.1   131072.0 69950.3     40    7.176   0      0.000    7.176
34944.0 34944.0 17625.0  0.0   279616.0 83850.1   699072.0   86240.1   131072.0 69950.9     40    7.176   0      0.000    7.176
 

by 돌쇠 | 2007/08/06 15:33 | Java | 트랙백 | 덧글(0)

GC (Gabage Collector)

GC (Gabage Collector)

 

Sun JVM 의 Heap Memory 영역은 다음과 같은 구조를 가진다.

 

 

[ Sun MicroSystems Memory 구조도 ]

 

위의 그림을 보면 메모리 영역은 다음과 같이 커다랗게 3부분으로 나뉘어진다.

1. Young Area
   - Eden
   - Survivor Spaces 2 block (S0, S1)
   - Virtual
2. Tenured Area (Old Area 라고도 부른다.)
   - Tenured
   - Virtual
3. Permanent Area
   - Perm
   - Virtual

* 보통 메모리를 명확하게 java -Xms1024m -Xmx1024m -XX:MaxPermSize=128m 형식으로 할당하기 때문에
  Virtual 영역은 없다고 보면 된다.

Java 실행시 Heap Size 를 주게되는데 설정된 Heap Size 를 설정된 Ratio 별로 나누어서 할당하게된다.
(Ratio 중에는 Young : Tenured 영역 분할 Ratio, Young 중에서 Eden : Survivor 영역 Ratio 가 있다.
자세한 사항은 이번 글에서는 넘어간다. -_-;)

그럼 위의 3가지 영역을 설명하면서 GC 되는 절차를 알아보자.

1. Young Area
 보통 객체 생성시 new 라는 keyword 를 이용하는데 이때 객체가 생성되는 부분이 Young 의 Eden 부분이다.
 Eden 부분에 객체가 생성되면서 메모리를 할당받게 되고 Eden Area 의 설정된 % 이상으로 메모리가 할당되면
 Young GC 가 일어나게 된다. (GC 의 종류도 참 많다. --;)
 이때 Young GC 가 일어나면 어떤 현상이 벌어지는지 눈 똑바로 뜨고 글을 읽어라.
 
 - Young GC
 Survivor 영역은 그림에서 보면 두개로 나뉘어져 있다. 각각을 S0, S1 이라 부른다.
 Eden 의 설정치 만큼 메모리가 할당되게 되면 Young GC 가 일어나는데 Young GC 란 Eden + S0 (처음 Young GC 일때)
 의 영역을 GC 를 실행한다. 이때 GC 대상에 포함되지 않는 (즉, Reference 가 살아있는 객체) 객체는
 S1 영역으로 옮겨지고 나머지 Week Reference 객체는 GC 된다.
 그후 다시 Eden 에 객체가 생성되고 메모리가 또 차게되면 이번에는 Eden + S1 이 GC 의 대상이고 이때 동일하게
 Reference 가 살아있는 객체는 S0 영역으로 옮겨지고 나머지 Week Reference 는 GC 된다.
 
 그럼 이말을 잘 풀어서 보면, Eden 은 무조건 GC 대상이고 Survivor 의 두 Area 가 돌아가면서 GC 대상이 되는것이다.
 Young GC 가 될때는 Eden + Survivor Area 중 한곳의 메모리를 전부 비우게 되며 Refrence 가 남아있는 객체를 다른 한곳의
 Survivor Area 로 할당하게 되는것이다. 즉, Survivor Area 의 S0 or S1 둘중에 한곳은 항상 비어있다고 보면 된다.
 
 그럼 Singleton Pattern 형식처럼 항상 메모리에 상주하게 구현한 객체들은 S0 와 S1 사이를 왔다리 갔다리 한다는 말인가?
 흠... -_-;
 정답은 안그렇다.
 
 java option 에 TenuringThreshold (default 32) 값에 의해서 S0, S1 을 몇번이상 왔다리 갔다리하면 이것은 오래 남을 객체라
 판단하고 Tenured Area (Old Area) 으로 보내진다.
 또한 Eden 10M, S0 1M, S1 1M 라고 했을때 Young GC 가 Eden + S0 가 일어날때 GC 후의 값이 5M 라면 어떻게 될까?
 정답은 S1 에 1M 를 할당하고 남은것은 Tenured Area 로 보내진다.

2. Tenured Area
 Old Area 라고도 부르며 Young Area 에서 넘어온 객체들이 할당되어진다.
 Tenured Area 역시 설정된 % 이상으로 메모리가 할당되면 GC 가 일어나게 되는데 이것이 Old GC 이다.
 Old GC 가 일어나도 Old 영역이 줄어들지 않는다면 Full GC 가 일어날 수 있으며 Memory Leak 을 생각해 볼 수 있다.

3. Permanent Area
 Permanent Area 는 Class 를 Loading 하는데 사용한다. 보통 Perm Size 는 64 이며 크게 잡을경우 128 을 잡기도 한다.
 개발 환경에서는 Hot Deploy 가 편하지만 운영환경이라면 Hot Deploy 하는것이 좋지않다.
 Hot Deploy 하게되면 Permanent Area 로 Class 가 Loading 되게되며, 기존의 Loading 되어있던 Old version 이 바로 Unloading 되는것은
 아니기 때문이다. (Permanent Area 의 경우 GC 라 하지않고 Unloading 이라 부른다.)
 문제는 수행중에 필요에 의해서 Unloading 이 발생하게 되는데 수시로 Hot Deploy 가 일어나서 Permanent Area 가 Full 나게되면
 Full GC 가 일어나게 된다.
 Loading 해야될 Class 보다 적은 Permanent Size 를 할당할 경우 Full GC 도 수시로 일어나지만 OOME (Out Of Memory Error) 가
 발생하며 WAS 가 down 될 수도 있다.
 

** Full GC 란 ?
 Old GC 후에 Tenured Area 이 줄어들지 않았을 경우 발생 할 수 있으며 또한 Permanent Area 가 Full 나면 일어난다.
 Full GC 가 일어나면 보통 수초에서 수십초의 시간을 소요하게 되며, 이때 JVM 은 Full GC 이외의 일은 하지 않는다.
 즉, 일반 상용 사이트의 Web Application Server 가 Full GC 가 일어나면 수초에서 수십초간 WAS 가 정지되는
 상황에 놓이는 것이다. 그러나 사이트가 정지되는 일은 별로 일어나지 않는데 이유는 일반 상용 사이트는 HA (High Availibilty)
 구성을 해놓기 때문에 한쪽 WAS 가 먹통이 되면 L/B (Load Balancer) 가 알아서 Load Banlancing 을 하게됨으로 일반 Client 가 사용하기에는
 아무런 문제가 발생하지 않는다.

 Full GC 가 일어난다는 것은 메모리 할당이 잘못됐거나, Memory Leak 발생하거나 하는 경우이므로 튜닝 포인트를 찾아내야한다.

by 돌쇠 | 2007/08/06 15:32 | Java | 트랙백 | 덧글(0)

[발칙한 와인]휴가 바구니속 ‘달콤한 낭만’


뙤약볕에서 장거리 차로 이동해야 하는 휴가철. 사람보다 와인이 신경쓰이니 이 또한 고질병이다. 온도가 높은 트렁크 속에 덜렁 와인을 넣어 놨다간 끓어 넘쳐 낭패 보기 십상. 플라스틱 작은 병 샘물 3개 정도를 미리 얼려 아이스박스 속에 와인과 함께 넣으면 실용적. 와인은 수건으로 감싸고 사이에 냉동샘물을 끼워 움직이지 않게 한다. 생수도 차갑게 마시고, 와인도 보호하고, 도착하여 바로 한 잔 할 수 있으니 일석삼조. 개인적으로 얼음은 지방에도 24시간 편의점이 흔하니 필요할 때마다 칵테일용을 구입, 아이스박스에 넣어놓고 사용하니 편리했다. 아울러 샐러드를 위한 몇 가지 양념 준비도 잊지 말자.

*준비할 양념 : 올리브 오일, 발사믹 식초, 후추, 바질, 꿀, 소금, 디종머스터드(미국산은 달아서 프랑스산이 좋다), 간장 그리고 안주용 치즈 1~2개.


해지는 오후, 야자수 그림이 그려진 커다란 보자기를 나무그늘에 깔고 지중해풍 카프레제(Caprese) 샐러드를 준비하는 거야. 자른 토마토 사이에 모차렐라 치즈를 한 조각씩 켜켜이 넣고, 그 위에 올리브 오일과 발사믹 식초를 끼얹은 후 바질만 뿌려주면 완성. 알잖아? 쉽지만 시각적인 즐거움과 맛은 어느 샐러드보다 만족도가 높은 것! 자, 그럼 샴페인을 따야지. 우리들의 아름다운 휴가를 위해, Cheers!

휴가. 글쎄 어느 때부터인가 ‘3박4일간 느린 호흡’이라고 생각해 왔다. 팍팍한 일상의 끈을 놓고 자연 속으로 들어가 새벽 산책을 즐기며, 책 한 권 읽다 오수에 빠지고, 이른 저녁 산그늘 아래 소풍가방을 펼쳐 조금은 낭만적인 식사와 와인 한잔 즐기는 것. 해서 조급증을 털고 삶의 여유를 되찾는 것. 행복한 추억으로 1년치 낭만 세포들을 재생시키는 것.

그러니 올 ‘휴가 바구니’는 색 다르게 준비해보자. 날도 더운데 손이 덜 가는 샐러드와 화이트 와인의 어울림은 어떨지. 와인은 2만~3만원대로 골라 봤다.

어디서든 샴페인 한두 병 있으면 기분도 띄우고, 식욕 촉진 효과가 있다. 스무 살처럼 싱그러운 스페인 카바 프레시넷 코든니그로는 어떨까. 200㎖ 딱 한잔짜리 작은 병도 있다. 같은 크기로 독일 헨켈 트로켄 피콜로도 사랑스럽다. 씹히는 기포가 감미로운 말바시아 품종의 이탈리아 바바 로제타(375㎖)면 여인들 웃음이 깨꽃처럼 쏟아진다. 샴페인은 따면 다 마셔야 하므로 이런 ‘미니’ 몇 병 냉장고에 넣어두면 요긴하다. 최근에 마셔 본 프랑스 알사스 크레멍 ‘카페 드 파리’도 가격 좋고 카나페 등과 곁들여 식전주로 마시기 경쾌했다.

화이트 와인은 풀 향기가 싱그러운 뉴질랜드 소비뇽 블랑이 좋겠다. 초보자들도 흠뻑 빠질 수 있는 킴 크로포드와 달콤한 과일 맛의 빌라 마리아 프라이빗 빈은 후회 없는 선택. 새콤달콤한 리슬링 품종의 독일 쉴라스 폴라드나 닥터 루젠 카비넷도 소풍 단골 와인들. 한국음식과 곁들여도 오지랖이 넓다. 또 닭고기 등 가벼운 육류요리에도 눌리지 않는 프랑스 론 지방 타벨 로제나 과일 한 접시 놓고 홀짝거리기 좋은 미국 셔터 홈 화이트 진판델도 권할 만하다. 중요한 것은 이 와인들 모두 차갑게 마셔야 한다는 것. 따라서 마시기 1~2시간 전 냉장고에 넣어 놓거나 오목한 용기에 얼음을 담아 병을 꽂아 놓고 마신다.

그럼 즉석 안주 몇 가지 살펴보자. 첫 단락에서 언급한 카프레제는 화이트 와인과 훌륭한 콤비다. 모차렐라는 백화점 치즈코너에 가면 있다. 생치즈여서 유통기간이 짧으니 날짜를 꼭 확인토록. 메론을 쩍쩍 갈라 조각마다 짭조름한 프로슈트(Prosciutto)햄을 얹으면 와인과 둘도 없는 짝꿍. 아울러 새 순을 준비, 올리브오일과 발사믹 식초, 약간의 꿀, 후추를 얹은 즉석 샐러드도 풋풋한 소비뇽블랑과 상큼하게 어울린다.

오후에 촐촐해지면 있는 재료로 ‘쌀국수 비빔면’에 도전해보자. 고추장은 안 들어간다. 양파 반개, 피망 반개, 팽이버섯 약간, 청양고추 2개를 모두 다진 후 올리브오일 3술(밥수저)과 간장 1술, 식초 1술, 후추, 디종머스터드 약간 넣고 섞어 놓는다. 쌀국수는 끓는 물에 3분 정도 삶아 찬물에 헹군다. 섞어놓은 양념과 버무리면 여름 날 특별한 별미다. 물론 화이트 와인 한잔이 곁에 있어야 할 것이다.
출처 : 스포츠칸
 

by 돌쇠 | 2007/08/01 18:24 | Wine | 트랙백 | 덧글(0)

제 1회 Vin de Shinsegae (뱅 드 신세계)

제 1회 Vin de Shinsegae (뱅 드 신세계)

▶ 행사기간 : 8/24(금) ~ 28(화), 5일간, 신세계 강남점 9층 이벤트홀(180평)

▶ 와인 참여업체

: 금양 INT, 나라푸드, 길진INT, 까브드뱅, 두산, 신동와인, 레뱅드매일, 루벵코리아,
모엣헤네시, 바쿠스, 빈티지코리아, 한독와인 外

▶ 와인 ACC + 셀러 참여업체

: 리델, 슈피겔라우, 삼진ACC, LG전자, GE, 와인앤푸드, NCHEESE 外

1> 각 와인회사별 와인 20~50% 파격 세일

2> 인기 와인 1/2/3만원 균일가 방출

3> 신의물방울 그랑크뤼, 프리미에르크뤼, 신대륙 명품 와인 경매 (와인 가격 10% ~)

- 경매일자 : 8/24(금), 오후 2시부터
- 예> 샤또 딸보 경매가 12,000원 부터 ^^

4> 보르도 그랑크뤼 61종 와인 시음회

- 행사 5일간 매일 오후 2시 / 4시

5> 5일간의 와인 무료 테마강좌 및 시음회

- 8/24(금), 오전에 칠레 CONCHA y TORO 와인메이커 방문 예정
- 일정 차후 공지 예정

6> 와인 ACC, 와인셀러 진열상품 50% 파격 할인

by 돌쇠 | 2007/07/30 14:08 | Wine | 트랙백 | 덧글(0)

[France] Opera, Demi Sec ,Cfgv - ready

오페라 데미 섹, Cfgv
Opera, Demi Sec ,Cfgv
권장소비자가:15,000원
상품번호:1104307383
와인의 종류:스파클링(Sparkling)
빈티지:NV
생산자:C.F.G.V
지역:프랑스기타지역(France ETC)
생산국:프랑스(France)
회원사(수입원):까브드뱅
병사이즈:750 ml
음용온도:7-10 C
포도품종:우니블랑(Ungi Blanc)
어울리는 음식:샐러드, 가벼운 식전 음식
테이스팅 노트:볏짚색을 띠고 싱싱한 풋 사과향과 갓 구운 듯한 고소한 빵내음이 깊이 있는 아로마를 제공하고 드미섹 답게 달콤함이 풍부하게 입 안을 감싸는 미디엄 바디의 와인이다.

CFGV

 

1909년에 포도주 양조학자 이자 “탱크 내 2차 발효” 기법을 발명한 Eugene Charmat 에 의해 설립되었다. 그는 또한 스파클링 와인 산업을 부흥시킨 장본인이기도 하다. 1988년, CFGV는 Veuve Amiot House를 합병했고 1991년에는 Wissenbourg 공장을 인수 하는등 프랑스 스파클링 와인 생산의 선두주자이다.

 

지역 : 프랑스

 

품종 : Ungi Blanc

 

양조과정

샹파뉴 양조 방식을 그대로 사용했으며 병내 2차 발효 진행. 샹파뉴 보다 작은 압력의 CO2 생성하였다.

 

테이스팅

볏짚색으로 상큼하고 달콤한 과일 향이 조화를 잘 이뤘고 싱싱한 풋 사과향과 갓 구운 듯한 고소한 빵내음이 깊이있는 아로마를 제공한다.

Medium  Body와인으로 Demi-Sec 답게 달콤한이 입안을 풍부하게 감싼다. 감칠맛 나는 신선한 미감이 화려한 과일향들과 어우러져 안주 없이 가볍게 마실 수 있으며 과일 케잌과 함께 마시거나 아페리티프로 이용하면 좋다.

by 돌쇠 | 2007/07/23 19:01 | My Wine History.. | 트랙백 | 덧글(0)

[와인병의 크기]


1.쿼터 보틀(Quarter bottle) : 200ml. 일명 미니 보틀
2.하프 보틀(Half bottle) : 375ml. 일반 병의 반 사이즈라 하프 보틀이라 부릅니다.
3.보틀(Bottle) : 750ml. 가장 일반적인 사이즈로 6잔을 따를 수 있답니다.
4.매그넘(Magnum) : 1500ml. 일반 보틀의 2병 사이즈
5.마리잔느(Marie-Jeanne) : 2250ml.일반 보틀의 3병 사이즈
6.더블 매그넘(Magnum) : 3000ml.일반 보틀의 4병 사이즈
7.제로(여로)보암(Jeroboam) : 4500ml.일반 보틀의 6병 사이즈 (미국은 5000ml)
8.임페리알(Imperiale) : 6000ml.일반 보틀의 8병 사이즈

by 돌쇠 | 2007/07/23 18:44 | 트랙백 | 덧글(0)

대한항공 보잉787

본문스크랩보잉787
 


최근 서울 강서구 공항동 대한항공 김포 본사와 서울 중구 남대문로2가 한진빌딩은 사진 촬영‘명소’로 떠올랐다. 대규모 항공기 그림 래핑이 고객들의 입소문을 탔기 때문. 대한항공이 건물 전체를 뒤덮은 래핑을 선보인 것은 지난 8일 미국 시애틀에서 세계 시장에 첫선을 보인 B787 차세대 항공기 도입을 계기로 마케팅을 본격화하기 위해서다.

대한항공이 변화의 물결이 거센 세계 항공시장에서 주도적 입지를 다지기 위한 항공기 도입 전략에 심혈을 기울이면서 결과에 관심이 쏠리고 있다. 그 요체는 바로 B787이다. ‘드림라이너(Dreamliner·꿈의 비행기)로 불리는 이 항공기는 미국 보잉사가 제작한 차세대 고효율 기재로, 2009년부터 순차적으로 대한항공에 들어온다.

◆‘드림라이너’로 아프리카 등 신규 시장 개척 = 대한항공은 B787 항공기 공개행사에 맞춰 B787 차세대 항공기를 비롯해 A380 차세대 초대형 항공기 및 B777 - 200ER, B777 - 300ER 등을 중심으로 한 장거리 항공기 운영방안을 발표했다.

이에 따르면 B787 차세대 항공기는 남미, 아프리카 등 장거리 신규 노선 개척에 적극 활용하고, A380 차세대 항공기와 B777 - 200ER, B777 - 300ER 항공기는 북미, 유럽 등지의 주요 대도시에 집중 투입한다.

B787 차세대 항공기는 최첨단 기술이 집약된 200~300석급 미래형 항공기다. 기체의 절반 이상이 가벼운 첨단 탄소복합소재로 구성돼 있다. 동급 항공기 대비 연료 효율을 20% 이상 높여 중형 항공기임에도 불구, 마하 0.85의 속도로 약 1만6000㎞를 비행할 수 있다. 대한항공 관계자는 “자체모니터링 시스템 등을 통해 유지보수 비용을 20%이상 줄였고, 가스 배출과 이·착륙때의 소음을 대폭 낮춘 환경 친화적인 항공기”라고 말했다.

승객편의성도 눈에 띈다. 다른 항공기보다 65% 더 커진 전자 제어 창문과 기내 천장의 발광다이오드(LED) 화면을 통한 가상하늘의 연출 등 인체공학적 기내 인테리어로 기내 환경을 개선했다.

승객들이 보다 안락하고 쾌적하게 항공여행을 즐길 수 있도록 하자는 배려다.

◆최신형 항공기로 주력 기종‘업그레이드’= 이런 장점과 효용성을 지닌 B787은 공개도 되기 전에 이미 각 항공사에 600대 이상 수주됐다. 보잉사가 오는 2014년까지 더 이상 주문을 받을 수 없는 상태. 이미 차세대 항공기 확보 전략을 수립한 대한항공은 2005년 4월 보잉사와 B787 차세대 항공기 10대를 도입하는 계약을 맺어 론칭파트너로 참여했다. 옵션으로 10대를 추가 구입하는 계약도 체결, 시장 상황에 탄력적으로 대응할 수 있는 길을 마련했다.

대한항공은 앞으로 B787 항공기를 포함해 에어버스사의 초대형 A380 차세대 항공기 5대 등 최신형 항공기 40대를 2009년부터 순차적으로 도입한다. 주력 기종을 차세대 기종으로 완전 업그레이드해 나갈 계획.

대한항공은 B787 차세대 항공기가 첫선을 보인 것을 기념해 김포 본사빌딩과 소공동 한진빌딩을 항공기 그림으로 뒤덮는 래핑을 선보인데 이어 8월31일까지 홈페이지(www.koreanair.com)를 통해 다양한 B787 차세대 항공기 이벤트를 펼친다. 9~10월 출발하는 미국(로스앤젤레스, 라스베이거스, 샌프란시스코, 시애틀), 유럽(빈, 취리히, 암스테르담), 호주(브리즈번) 등 8개 노선의 항공권을 78만7000원이란 파격적인 가격으로 제공한다.

by 돌쇠 | 2007/07/16 10:14 | News | 트랙백(3) | 덧글(0)

◀ 이전 페이지 다음 페이지 ▶