프로그래밍 관련/게임프로그래밍

매니지드 언어(Java, C# 등등) 로 MMORPG 만들기 어떤가요?

AlrepondTech 2020. 9. 13. 18:59
반응형

 

 

 

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

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

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

 

 

 

 

 

 

 

출처: http://www.gamecodi.com/board/zboard.php?id=GAMECODI_Talkdev&no=3824

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#을 써야할까?'


와 같은 얘기 -_-




어떻게 생각하시나요?

맨날 나오는 떡밥 같아요.

GDC2014나 카더라 통신에 따르면 


lol 서버의 많은 부분이 자바로 되어 있다고 합니다.


언어보다는 클라이언트 로직의 활용이 


선택 기준이 아닐까 합니다.
2016-02-04
09:14:05

 
    ㄴ lol 서버 대부분이 자바인가요? ㄷㄷ 몰랐네여 2016-02-04
10:00:39

 
    gc 돌때 월드가 스탑하는 일이 사실인지부터 확실히 해야 할것 같은데요??

2016-02-04
10:05:50

 
   

gc가 걱정되면 미리미리  gc를 강제로 실행하면 부하가 분산되지 않나요?




최대치까지 올라서 한꺼번에 부하를 처리하도록해서 이런 문제가 생기는게 아닌지...

2016-02-04
10:07:33

 
    C# 이나 자바의 경우 쓰다보면 편의성이 좋아 의식하지 못한채 마구 끌어다가 쓰는 경우가 많은 듯...


메모리 관리를 최대한 철저히 계획하에 설계하면 가능할 것으로 생각되나 혼자 서버를 다 코딩하여 만들면 몰라도 협업으로 할 경우 모든 작업자가 철저히 관리 한다고 가정하기는 힘들 수도 있죠....

누구 하나가 계획없이 마구 끌어다 써 버리면 거기서 바로 터질 수도 있는 문제이니....


개발 참여자가 모두 언어의 특성을 잘 이해하고 세심하게 설계하여 쓴다면 괜찮을듯 합니다.
2016-02-04
10:14:06

 
   


유니티로 프로그래밍할때
2016-02-04
10:15:19

 
    @노코드님 // 
제가 개발했을때는 minor GC가 아니라 full GC 상황에선 확실히 잠시라도 멈췄습니다. 
full gc 일때 stop이 안 일어나는 방법이 있을까요? 

@뿌요뿌요님 //
확실히 concurrent gc 상황에서는 별 이슈가 안되는데요, concurrent gc 던 full gc 던 코드레벨에서 개발자 의도대로 즉시 gc를 수행시킬수는 없는걸로 알고있습니다. 물론 코드 자체는 존재해요 객체마다 gc시점에 자원 정리하는 finalize() 메소드도 있고 system.gc() 도 있습니다. 하지만 이건 디버그 상황일때고, 저걸 호출한다고 해서 실제로 그 시점에 gc가 수행됨을 게런티하고 있지는 않는걸로 압니다.
2016-02-04
10:15:38

 
    아 참 저는 서버사이드 쪽에 대해서 얘기하고 있습니다. 
클라이언트 쪽은 이미 많이들 쓰시는 유니티 때문에 c#에 익숙하실거라 생각이 들고... 유니티로 만든 클라이언트는 실제로 기기에서 어떤식으로 동작하게 되는지 잘 모르겠네요. 개발언어는 C#이지만 실제 기기에서 mono나 .net 위에서 돌지는 않겠죠?
2016-02-04
10:23:22

 
    full GC는 자바쪽용어 같네요. 자바는 안써봐서 잘 모르겠어요 ㅎ
C#에서 GC가 일어나면 한 쓰레드만 블럭된다고 어디서 본것 같아요. 블럭되는 시간도 짧구요. 1ms~10ms 정도.
아무래도 C# .net이 우선 메인이 윈도우플렛폼이니 윈도우엔 잘 최적화 된듯해서.
C# core라고 멀티플랫폼 버전도 나오는듯 한데..이건 성능 쪽에서 걱정이 됩니다.
모노 같은경우도 동적할당이 일어나면 성능이 형편 없이 떨어지는 경우도 있더라구요
유니티에서 C#코딩이 PC에선 잘도는데 디바이스에서 돌려보니 크게 느려지는 경우도 옆자리 플머가 당했었고.
비슷하게 java라면 여러 플랫폼을 다 지원해야 하니 최적화에서 어려울듯도 하네요.

2016-02-04
10:25:33

 
    뿌요뿌요 / gc의 가장 큰 문제는 강제로 실행해도 해줄 수 있냐고 물어보는 의미이지 당장 해준다는 의미가 아니라서 입니다. 그래서 전 gc가 싫어요. 두 번 싫어요. 2016-02-04
10:26:22

 
    Full GC 상황에선 확실히 멈춥니다. Full GC 가 걸리면, 못해도 1초는 정말 스톱됩니다.

그런데요...제가 C# 은 안하고 Java 만 계속 하고 있는데(게임 서버는 2년 반 밖에 안되서...죄송) Full GC 을 호출하는 코드를 작성해본 적도 없고, 제가 운영하는 중에 Full GC 가 걸린 적도, 걸린다는 느낌을 받은 적도, 느낌을 받았다는 사람도 본 적이 없습니다.

심지어 1:1 로 대전하는 한붓긋기 형태의(붓 긋는게 되돌아가기도 되고, 그게 상대방에게 계속 전송되기 때문에 네트워크 사용량이 간헐적으로 발생하는 건 아니었습니다) 게임을 하면서도 마찬가지였습니다.

아직도 가장 성능상의 이유가 가장 많은 것도 GC 이고, 가장 많이 개선되고 있는 것도 GC 이지만, Full GC 가 안일어나게 습관적으로 코딩하는 방법도 많이 알려져있고, VM 개발자들도 그런 부분에 신경써서 개발하고 있기 때문에 "Full" 이라는 것을 맞닥드릭게 되는 일은 거의 없을 겁니다.

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

2016-02-04
10:27:51
 
    ** 작성자(또는 관리자)에 의해 삭제된 댓글입니다 ** 2016-02-04
10:30:01

 
    // 
c#의 경우  gc가 멀티쓰레드에서 이루어진다는것이죠


제가 궁금한건 이런겁니다
 
gc가 멀티쓰레드로 동작하도록 설계했다는건 , 메모리 할당과 실제 해제를 동시에 서로 다른 쓰레드에서 처리할수 있다는것이죠.




제가 설계했다고 생각해도  약간의 부하는 있을지언정 , 주쓰레드가 블럭될 일은 없을거 같은 느낌입니다.




좀더 심도 있게 생각해보면 


gc 쓰레드가  참조 포인터 즉 - 레퍼런스를 돌면서 실제로 참조 되지 않은 메모리를 골라내는 일은 


gc 쓰레드에서  atomic 연산 한번이면 골라 낼수 있고 ,  그런 메모리의 실질적인 해제는 주 쓰레드와 상관없이 독립적인 메모리로써 gc 쓰레드가 주쓰레드와 동기화 없이 처리 가능할수 있을것입니다.




gc가 ,  멀티쓰레드로 동작하고 있다는건 이미 그런처리를 하고 있다는게 아닐지요?
2016-02-04
10:31:47

 
    full gc 라는게 전체 메모리 위치를 정렬하는거라 멈추지 못하게 하는법은 없습니다.

하지만 요즘은 옛날처럼 한번에 모든 정렬를 하는게 아니고 나누어 진행을 합니다 


그래서 옛날처럼 체감하기 힘듭니다




다시 시작점으로 와서 


C++로 메모리 컨트롤 로직이 좋을까? 


아니면 C#, Java의 GC 로직이 좋을까? 라는 고민을 했을때 


비슷하지 않을까 생각 합니다

2016-02-04
10:33:48

 
    그리고, Full GC 때문에 혹은 PermGem Space Full 등의 오류를 만났다고 메모리를 늘리는건 해결책도 아니고 바람직한 방법도 아닙니다. 뭔가 누수가 있는지 조사하는게 맞는 해결책입니다. 보통 서버를 구축할 때 피크 타임이라도 해도 메모리를 100% 다 쓰는 정도로 메모리에 뭘 담도록 하진 않기 때문에(모든걸 메모리에서 처리하려고 한다면 예외겠지만) miner GC 의 빈도를 좀 줄이는 건 몰라도 Full GC 나 Memory Full 관련 오류의 해결책은 절대 될 수가 없습니다.

이럴 땐...Java 기준으론...제니퍼 사주는 겁니다. -_-;;;

2016-02-04
10:34:28
 
    ** 작성자(또는 관리자)에 의해 삭제된 댓글입니다 ** 2016-02-04
10:42:13

 
    아무래도 gc 성능은 버전마다 플랫폼마다 언제 달라질지 알 수 없는것 같은데
툴을 하나 만들어서 돌려보고 싶네요
게임서버와 비슷한 메모리 사용 패턴을 시뮬레이션 하는 툴
그리고 블락이 되는지 알수 있도록 로그 같은거 남겨서
1주일쯤 띄워놓기

2016-02-04
10:44:25

 
    JAVA 모니터링에는 제니퍼만한 솔루션이 없기하죠 ㅋㅋㅋ 2016-02-04
10:44:31

 
    네... 근데 저도 사실 java로 프로젝트하면서 full gc를 맞아본적이 거의 없는거 같습니다. 
대부분이 비정상적인 상황(메모리 릭) 상황에서 old영역으로 객체들이 많이 넘어가서 그렇고 잘 관리되고 있을때는 world stop을 유발하는 gc가 얼마나 유의미한 빈도로 일어나느냐가 좀 궁금한데, 장담할 수 없는 변수를 놓고 매니지드 언어를 MMORPG 규모의 프로젝트에 사용하려고 결정하기는 쉽지 않을거 같다는 생각이뜨네요. 

걱정하는 이유는 제가 C++ 고자가 된거 같아서 그렇습니다. ㅠㅠ..
2016-02-04
10:44:45

 
    //아이아빠 
그런거라면 C++도 마찬가지 같네요  new delete 같은걸 많이하면 
쪼깨진 메모리를 더 유효하게 재사용하기 위해 메모리 정렬를 합니다.
 
그때 엄청난 부하가 걸리죠.
 
예전부터 new delete 많이 하지말라는 이유가 , 그런것때문이지 않았나 싶습니다


[그리고 이건 full 정렬 할일이 없을거 같네요 , 필요한만큼 부분 정렬을 하는걸로 압니다
정렬 알고리즘은 유닉스 내부의 책을 보면 3-4개는 본거 같네요, 
성능을 위해 메모리 낭비하는 정렬, 메모리는 최대효율을 내지만 성능은 많이 먹는 정렬 등등 ]




또한 플레폼 마다 다르겠지만 , 힙메모리는 운영체제 영역이라 운영체제가 
보통 하는걸로 알고 있습니다.
[ 컴파일러가 그런걸 제공해줄수도 있겠죠,  윈도우는 아예 로우 레벨로 힙메모리 관련함수가 꽤 
존재했던걸로 기억되네요 ]

2016-02-04
10:44:50
 
    제 기억에도


확실히 C++에서는   full 정렬은 거의 안하는거 같더군요


차라리 그냥 메모리 할당 실패를 해버리는 경우가 대부분입니다




그래서 32비트에서는 2기가 사용가능한데  여러종류의 크기를 매우 많게 할당하면
보통 1.4-1.5기가 정도에서 ,메모리 할당에 실패를 하곤했죠


특수하게  많이 조깨질 일없는  일관된 메모리를 사용하면  1.9기가는 사용했었는데 말이죠

2016-02-04
11:57:57

 
    c# 으로 서버 짤때 풀 사용을 많이 합니다
그럴꺼면 c# 왜 쓰냐고 하는 분들도 간혹 있는데
메모리 관리 안할려고 c# 쓰는게 아니므로 잘못된 질문입니다
자바는 제가 잘 모르고 c#은 gc 레퍼런스 카운팅 아닙니다

제가 봤던 c# 게임 서버들은 대부분 풀을 사용 하고
gc 시간을 최소화 시키는 방향이였습니다
2016-02-04
13:39:10
 
    @arena 유니티 쓰시나요?
윈도서버.NET 이라면 풀 안만드는게 더 좋아요
개발자가 메모리 관리에서 자유로워 진다면 엄청난 능률 향상이 있는것인데


C#에서 풀을 만들고 할당/해제 시점을 매번 코딩 한다는건
스마트폰 사용하면서 전화번호부 따로 손으로 적어 다니는거랑 다를게 없다고 봅니다.
C++에서 제대로된 delete 시점을 찾기위해 맨날 밤새 고생 한걸 생각하면 ㅠㅠ

2016-02-04
14:04:00

 
    자바의 G1GC 라는게 생겼더군요.한번 참고하시기 바랍니다. 2016-02-04
17:53:54

 
    요즘은 그냥 새로 받아서 쓰고 버리는(혹은 잊는) 일들을 잘 하니까 아무래도 그런쪽으로 언어들이 잘 발전했다 생각됩니다.예전 WinCE 땐 CString조차도 자주 쓰면 메모리 고갈되곤 했었는데..
요즘은 정말 심각한 상황이 아니면 문제 없지 않을까요?
차라리 부하를 효율적으로 분산시키면서 Scalability를 높이는 것에 집중하는 것이 더 좋을 것 같아요.
2016-02-04
19:07:39

 
    뿌요뿌요// 메모리 정렬을 할 때 엄청난 부하가 걸린다는게 무슨 말씀이신지요?C++은 자체적으로 메모리 단편화를 해결하기 위한 기능을 가지지 않는 것으로 알고 있습니다.
단편화에 대한 부분은 OS에서 많은 부분을 해결하고 있습니다.


제가 알고 있는 Memory Alignment는 C#의 GC처럼 한순간 메모리 전체 영역을 순회하면서 정렬하는게 아니라 메모리 사용 영역을 효율화하여 page fault를 줄이는 개념입니다.


말씀하신 메모리 정렬이라는게 제가 알고 있는 C++의 개념과 다른 부분인지 궁금해서 질문드립니다.

2016-02-05
10:02:21
 
    //구떽 

제 글을 잘 읽어보시면 힙메모리를 OS가 정렬한다는 내용이 있습니다


new delete가 힙 메모리를 사용하고  그거에 대한 결과로 메모리 정렬을 사용한다는 의미죠


C++ 이 직접하는건 아니고 new delete를 통해 간접적으로 한다는 의미입니다




또한 플레폼 마다 다르겠지만 , 힙메모리는 운영체제 영역이라 운영체제가 
보통 하는걸로 알고 있습니다.
2016-02-05
12:06:11

 
    근데 모르죠  컴파일러에서  힙메모리를 어떻게 사용하느냐에 따라 좀 다른 결과를 낼수도 있으니까요

그래서 여지를 둔것입니다

2016-02-05
12:08:10

 
   

new delete 사용하면  각 OS에서 제공하는 힙 메모리 로우 함수를 호출하기 되고 힙메모리는 운영체제 차원에서 메모리 분할 및 할당 해제 알고리즘을 수행합니다.  


C++ 언어가 힙메모리를 new delete로  직간 접적으로 사용하기때문에 같은 의미라 봐도 되겠죠.



2016-02-05
12:15:47

 
    그거에 대한 내용은 유닉스 내부책의  커널메모리 할당과   어드밴스 윈도우즈 NT 2판(4판인가 5판까지 나온걸로암)  의 힙메모리 부분을 참고하시면 될거 같습니다


2016-02-05
12:17:30

 
    // 뿌요뿌요

OS가 메모리를 정렬한다는 것또한 저는 들어보지 못했습니다. 적어도 Windows OS 환경에서 C++에서 new delete가 빈번하게 일어나는 것으로 인해 page fault나 memory fragmentation으로 인한 vertual memory 부족 이 외에 OS가 메모리를 정렬하기 위해서 부하가 걸리는 경험을 한적은 없어서요.


혹시 OS가 메모리를 정렬한다는 것에 대해서 조금 자세히 설명해 주실 수 있을까요?
제가 Windows 환경밖에 겪어보지 못해서 다른 OS에서 어떤 목적으로 정렬을 수행하는지라도 알고 싶어서요.

2016-02-05
12:38:38
 
   

// 구떽


힙메모리는 옛날 윈도우 기준으로  프로세스당 1메가 를  할당 받고 ,  더 필요하면  더 크게 할당합니다
 


그리고 그 메모리는 선형으로 있거든요?  근데 그 선형 메모리를   여러가지 크기로 메모리를 할당해서 주려면  운영체제마다 각기 다른 방법으로 메모리를 할당합니다


그 선형 메모리를 쪼개는 방법은 운영체제마다 다릅니다


일반적으로   ,  메모리를 가장 효율적으로 쓰지만  가장 느린 알고리즘 류와  메모리 낭비는 좀 심하지만 분할 및 할당속도는 빠른 알고리즘  으로 그 메모리를 쪼개서 주죠
 
그리고  , 할당 해제시  낭비되는 공간을 부분 정렬 및 합병도 이루어져서   메모리를 더 효율적으로 쓸수 있게도 합니다
 
아마 이건   일반 하드디스크 정렬할때 조각난 파일 정렬하는것과 조금 비슷하다고 볼수도 있겟네요
 
자세한건 제가 거론한 책을 좀 읽어보시거나 인터넷에 찾아보시는게 좋지 않을까 합니다.
 


 

2016-02-05
15:41:31
 
    유닉스의 내부라는 책을 보면   커널 메모리 할당이라는부분이 있죠

거기에 커널에서 쓰이는 할당 알고리즘에 대해 설명을 많이 하고


 
그 메모리를 쓰는 대표적인 함수로 malloc 과 free 같은 인터페이스가 존재하다고 설명합니다


 
거기서는 자유 메모리라고 부르지만 , 힙 메모리를 다른 이름으로 부르는거 같습니다
 
어떻게 남는  메모리를 분석 병합하는지  친절하게 알고리즘까지 다 설명해줍니다.
 
책에 잇는 내용을 다 옮겨 적을순 없으니 , 숙제로 남겨드리겠습니다

2016-02-05
15:47:01
 
   

참고로 윈도우 같은 경우 공간보다 성능 최적화 알고리즘을 써서 그런지  다양한 크기의 메모리를 할당시 
2기가 제한인데도 불구하고 , 1.5 기가도 사용하기 힘들더군요.
[게임 개발할때도 그랬고 , 실제로 다른 게임을 모드를 써서 메모리를 크게 사용할 경우에도 마찬가지였습니다.]




요즘은 메모리가 커져서  그런건지 , 힙메모리 할당과 해제 알고리즘이 윈도우 xp sp3 부터 성능위주로 크게 바뀌긴 했습니다만,   메모리 풀이 필요한곳은 여전히 존재하죠











2016-02-05
16:00:42
 
   

마지막으로 한마디 하자면 ,  다른분이 자바에서 경험하셨다는  full로 메모리 정렬은 ,
현존하는OS의  힙메모리 관리 알고리즘에상에는  존재 하지 않을거라 생각됩니다.
 
 
제가 보기엔  full 메모리 정렬했다는건 , 그만큼 메모리가 귀환 환경에서 동작하는 경우가 아니었나 싶고, 아주 옛날 메모리가 귀했던 시절의 자바의 메모리 관리 알고리즘이지 않았나 싶습니다.




요즘도 그렇게 full 메모리 정렬할지 매우 의심스럽군요.
 
 
c#으로 mmorpg 도 만든걸 보면 , 제 추측엔  자바 역시 메모리 관리 알고리즘이 많이 바뀌었을거라 추정됩니다.
 
 
 




 
 

2016-02-05
16:21:33
 
   



또 한가지 new delete 성능 저하를 별로 못겪어봤다고 하셧는데


아마 10년전에는 new delete 쓰지말라고 난리치는분이 엄청많았습니다.


심지어 면접할때도 N 모사 면접관이  new delete 남발하는지 체크하는분도 계셨구요




구텍 // 
 page fault나 memory fragmentation으로 인한 vertual memory 부족 이 외에 OS가 메모리를 정렬하기 위해서 부하가 걸리는 경험을 한적은 없어서요.

2016-02-05
16:42:29
 
    뿌요뿌요 // 설명 감사합니다.


제가 궁금한 것은 '메모리를 정렬한다' 라는 표현인데요.


프로세스가 시작되고나서 new delete가 매우 빈번하게 발생할 경우 fragmentation이 생기고 그로인해 메모리가 불필요하게 다수의 page에 기록됨으로 인해 쓸데없이 많은 page fault가 발생하면서 느려지는 것으로 알고 있습니다.
설명하신 내용을 보아도 memory alilgnment를 말씀하시는 건 아닌거 같네요.


OS가 임의로 특정 page에 기록된 메모리 영역을 다른 page로 옮김으로서 불필요한 page를 정리하는 기능은 없는 것으로 알고 있어서요. 말씀하신 '정렬' 이라는 표현이 정확하게 어떤 동작을 말씀하시는 건지 여전히 모르겠습니다.



2016-02-05
17:48:25
 
    구체적으로 질문드리자면 'full 메모리 정렬' 이 OS의 어떤 동작을 말씀하시는지요? 2016-02-05
17:53:43

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

맞습니다. 성능의 왕 LMAX 거래소도 Zing 을 사용하고 있다고 했습니다.
2016-02-05
18:02:06

 
    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 empty.

메모리 돈도 얼마 안하는데 그냥 널럴하게 놀게 하죠.
2016-02-05
19:37:07

 
    // coolspeed


힙메모리 관리자도 사실 스마트 힙이라고 , 예전에 느렸던 힙관리자 대용으로 나온 솔루션이 있었습니다.


힙메모리 관리자가 , 윈도우 xp3 이후 성능위주로 바뀐후에는 판매가 사라진거 같네요








// 구텍 

이정도 이야기했으면 이해할만도 할거 같은데 , 잘모르시겠다면 더 드릴말씀은 없을거 같네요


그리고 full 메모리 정렬이라는건 자바 gc에서 말하는것과 비슷한 행위를 하기에 비교해서 한말입니다




여기서 나온 이야기로 아직도 이해가 안가면 , 숙제로 드린 유닉스 내부라는 책을 한번 보시기 바랍니다.





2016-02-05
20:50:01
 
    뿌요뿌요// 왜 저한테 말씀하시는지 -_- 뭔가 다른 분의 발언을 제 발언으로 오해하셨는지, 아니면 제가 C++의 힙메모리 관리가 비효율적이다 라는 뉘앙스로 오해하셨는지?

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

2016-02-05
21:57:02

 
    몇가지 짜잘한 보충.

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

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

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

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

[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


2016-02-05
22:34:39
 
    //coolspeed 
다른 가상머신을 예로 들으셨길레  힙도 그런게 있어서 말씀 드린거고요
나머진   구텍님에게 말씀드린겁니다.
 


// <= 이걸로 누구에게 말했는지 구분자로 말씀드려서  오해하실만한 내용은 아닐거라 생각됐는데요
 

2016-02-06
00:02:33
 
    ㄴ 그랬었군요~ 저의 원문은 "HotSpot보다는 Zing이지!" 의뉘앙스였는데 C++ 힙을 말씀하셨길래 저에게 하는 말씀이 맞나 싶었었던 거에요~


2016-02-06
00:27:24

 
    // 뿌요뿌요

감사합니다. 일단 '유닉스 내부' 라는 책을 봐야겠네요.

2016-02-06
06:34:56
 
    저는 한번 할당된 메모리의 위치를 OS가 임의로 변경하는 일은 없는 것으로 알고 있어서요. OS는 할당 시 배치 전략을 최대한 smart 하게 만들어서 fragmentation을 방지하는 역할을 하는 것으로 알고 있었는데, 최근에는 OS가 메모리 위치를 임의로 변경하면서 정렬하는 기능도 있는가 보네요. 공부는 끝이 없네요 ㅠㅠ 2016-02-06
06:47:07

 
    ㄴ   정렬이라는걸  sort 의 의미로 받아들였다면 조금 다른 의미가 될수도 있겠지요 
관리라고 하는게 좀더 정확한 표현일겁니다.   할당시  분할 하는 알고리즘과 ,메모리 해제시,  자유 메모리를 분석하고 합치고 관리하는거니까요.
 
분할과 병합 알고리즘을  , gc가하는 정렬에 비유한거니까요




게다가  커널 단계에서 이루어지는거기때문에 ,  어차피  가상 메모리니까  유저의 메모리 주소 변경없이 내부의 메모리 주소자체를 다시 변경할수도 있을수 있는 방법도 가능할법도 한데 말이죠.









2016-02-06
10:50:15
 
    // 구떽 


 상식적으로는  일반적으로 할당된 가상 메모리를 수정할리는 없겠죠 , 그러면 유저단계의 포인터가 당연히 어긋나니까요.

그런식으로 이해할줄은 상상도 못했습니다 ㅋ


여기서  정렬은 할당된 메모리가 해제시에 자유메모리들을 더 크고 유연하게 사용하기위해  다른 자유메모리들과 병합하는걸 보통 말하는거라 보면 될겁니다.


 
그리고 풀 정렬의 의미는  모든 분할된 자유메모리들의  공간 최적화를 최대한 시키는 작업이겠죠.







2016-02-06
11:10:35
 
    // 뿌요뿌요

정렬이라고 하셔서 'sort'로 이해했습니다. 제가 알고 있는 OS에서 할당된 메모리 위치를 정렬해가면서 fragmentation을 줄이는 동작하지는 않는걸로 알고 있었거든요.


용어의 오해가 해소되어서 뭔가 시원하네요.
2016-02-06
11:10:50

 
    new, free를 자주 해서 발생하는 문제와 관련이 있는 것은 C++ runtime 수준에서 일어나는 일 아닌가요? OS에서의 free memory block의 관리와 할당과 직접적으로 연결되어있는 일은 아닐텐데요. 게다가 이것들 각각이 일반적인 GC의 비용과 어떤 접점을 가지고 논의하고 계시는지 모르겠습니다. 2016-02-06
17:02:12

 
    // 엘레게스
요약하면 C#에서 Pool 사용하지 않고 무분별하게 객체를 생성하다가는 Full GC 비용이 엄청 커지면서 괴로워 지는만큼 C++도 무분별하게 new, delete를 하다가는 큰 비용이 들어간다는 내용이 될것 같습니다.

리플 중 '메모리 정렬' 이라는 용어의 오해가 있어서 그게 뭔지 물어보다보니 내용이 길어졌네요.
2016-02-06
19:25:39

 
    ** 작성자(또는 관리자)에 의해 삭제된 댓글입니다 ** 2016-02-06
21:46:56

 
    C# Garbage Collection의 최선의 전략은 할당받은 객체의 generation이 2세대가 되기 전에 삭제하는 것이겠죠. 1,2세대는 GC 비용이 커지므로 가급적이면 0세대에서 GC가 될수 있게끔 하는 겁니다. 


그래서 C#에서 memory pool을 구현한후 아주 많은 객체를 pool에 저장하다 보면 결국 GC 2세대가 되버려서 되려 부담이 되는 거지요...


저는 C로 만든 memory pool DLL을 C#에서 갖다 쓰는 방식으로 이런 문제를 해결하고 있습니다.


물론 C# 객체를 C memory pool 에 저장하고 읽기 위해서는 직렬화/역직렬화 비용이 소모되긴 합니다만 GC의 부담보다는 적다고 봅니다. 

 

 

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

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

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

 

 

반응형