매니지드 언어로 MMORPG 만들기

사건의 유래는 게임코디에 어느분이 이런 질문을 올린겁니다.

MORPG까지는 만들어봤는데, 심리스한 MMORPG를 Java나 C#으로 ( 메이저 한 언어로 갑시다…! ) 만든다고 하면 막연히 가장 걱정되는게 Full GC 상황에서의 world stop입니다. 아무리 concurrent gc나 vm 옵션을 건드려서 최적화 한다고 해도 언젠가는 Full GC를 마주칠텐데 1초만 world가 멈춘다고 해도 썩 유쾌한 경험은 아닐거 같거든요.

두번째로는 최대가용 메모리 입니다. Full GC랑 연관이 있는데 결국 Full GC상황에서의 GC 수행시간은 vm에 할당한 최대 heap size에 어느정도 비례합니다. 이 주제를 놓고 지인들과 몇번 토론을 했는데 주로 나온 얘기들은…

‘마영전은?’
‘누가 시도해 본 사람?’
‘요즘 하드웨어 좋은데 괜찮지 않을까?’
‘C++ 놓은지 너무 오래되서…(?)’
‘최소화 할 수는 있겠다, 죄다 pooling 한다던가, 그런데 적당히 해야지 이럴거면 왜 java나 c#을 써야할까?’

와 같은 얘기 -_- 어떻게 생각하시나요?

프로그래머 커뮤니티에 흔하게 수주 주기로 올라오는 화제라고는 하지만, 질문자분의 폼이 “기본적인 건 지인들이랑 다 토론해봤다. 여기서는 정말 크리티클할 수 있는 Full GC에 초점을 맞춘다.” 라는 포즈여서 게임코디에서 나름 진지하고 심도있으며 참신하게 토론 됐던 것 같습니다.

원 스레드에서도 대답한 내용 들이지만, 저의 이 물음에 답들을 정리할겸 저장할겸 여기에 포스팅합니다.

zepinos:

Java 한정으로 팁을 드리면…돈이 여유가 있다면 Azul Systems 사의 Zing JVM 을 도입하세요. 전 돈 없어서 그냥 Zulu 쓰는데(설치가 편해서…쿨럭) 게임 만큼이나 성능에 민감한 미국 금융권에서도 잘 쓰고 있는 JVM 입니다.

맞습니다. 성능의 왕 LMAX 거래소도 Zing 을 사용하고 있다고 했습니다.

LMAX 는 full GC 를 피면하기 위해 24시간마다 한번씩 프로세스를 재시작 합니다. (어떻게 상태를 잃어버리지 않냐구요? 그건 다른 흑마법입니다 ㅎㅎ)

하지만 이건 600만 TPS 의 시스템에서나 쓸 필요가 있는 테크닉이고, 기타 시스템에서 Zing 을 사용하면 full GC 를 전혀 근심 안해도 된다고 합니다.

https://www.quora.com/Whats-the-best-way-to-avoid-garbage-collector-pauses-with-big-heaps-in-Java

(링크내 Java 구루들 출몰 주의. Oracle 개발자, Zing CTO …)

무료인 HotSpot 을 사용하더라도 메모리를 빡빡하게 사용하지 않고 메모리 관련 예외가 없는 이상 full GC 는 발생하지 않을겁니다.

zepinos 님 말씀

Full GC 때문에 혹은 PermGem Space Full 등의 오류를 만났다고 메모리를 늘리는건 해결책도 아니고 바람직한 방법도 아닙니다. 뭔가 누수가 있는지 조사하는게 맞는 해결책입니다

에 동의합니다.

Oracle 개발자도 이르기를:

I suggest a minimum of 1/3 memory empty.

메모리 돈도 얼마 안하는데 그냥 널럴하게 놀게 하죠.


그나저나 smartheap 이 안팔리는건 자체도 별로 안좋고 현대 컴파일러의 힙관리가 좋아진데다 (default malloc) 현대 OS의 가상메모리 관리도 좋아졌고 하드웨어도 좋아졌으며 무료인 tcmalloc, jemalloc, TBB malloc, boost malloc 등등이 완전 좋아지는 등 복합적인 원인 때문이겠죠.


몇가지 짜잘한 보충.

1. Full GC 는 Java 온리의 개념이 아닙니다. 자바쪽에서 많이 듣게 되는 것은 GC영역을 수십년 동안 혁신해오고 실험해오고 리드해온 선봉이였기 때문입니다.

2. 매니지드 언어라 해서 꼭 GC가 있는 것도 아니고 네이티브 언어라고 해서 꼭 GC가 없는 것도 아니죠. 일례로 go언어는 네이티브 언어인데 GC 가 있습니다. C/C++도 GC라이브러리가 있습니다. 비야니옹은 심지어 C++ 11 표준에 GC를 넣을려다가 구현은 다했는데도 다른 언어특성들과의 조화에 대해 고민을 못끝내서 안넣었다고 합니다[1][2][3].

3. Go언어의 GC중의 stop-the-world gc는 10 밀리세컨드를 넘지 않음을 보장하고, 대다수 경우 그것보다 훨씬 짧다고 합니다. (주의, 여기서는 stop-the-world gc 를 말하는거고 컨커런트 gc도 런타임에 작동하는데 이것은 당연히 유저프로그램과 병렬실행됩니다)

4. 콘솔에서 돌아가는 게임 엔진들은 메모리 파편관리를 자체적으로 하는데 (그래야만 하는 이유 있음) 한번에 하면 너무 오래 걸릴까바 프레임마다에 쪼개서 실행하는 흑마법을 사용합니다…


 

결국 성능을 위해 부득이하게 low-level 에서 생각하고, low-level에서 최적화할거면, 애초에 외 C/C++ 같은 bare-metal언어대신 Java같은 매니지드 언어를 선택하는가? 란 질문에 대해서는 아래 스레드가 잘 설명해주는 것 같습니다.

Why did the team at LMAX use Java and design the architecture to avoid GC at all cost?

 

References:

[1] http://www.stroustrup.com/bs_faq.html#garbage-collection
[2] http://stackoverflow.com/questions/147130/why-doesnt-c-have-a-garbage-collector
[3] http://lab.gamecodi.com/board/zboard.php?id=GAMECODILAB_QnA_etc&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=last_comment&desc=desc&no=4031

 

Advertisements

댓글 남기기

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s