2012년 1월 28일 토요일

Windows의 메모리를 관리해보자.

일반적으로 Windows 사용자 입장에서는 메모리 관리를 OS에 맡기거나 (즉 아무것도 하지 않거나), 저처럼 Freeware 를 사용하여 메모리를 관리하겠죠. 저는 IOBit Smart RAM 을 사용합니다만, 워낙 많은 Freeware 가 있으니 뭘 쓰던 그리 큰 문제는 아닙니다.

오늘 얘기하고자 하는 방향은 서버 관리자 입장에서 본 윈도우즈의 메모리 관리를 말하고자 합니다. 개인용 PC와는 달리 서버 시스템 특히 운영 서버의 경우에는 Freeware 같이 검증(?)되지 않은 것을 함부로 깔 수도 없습니다. 근데 이런 문제가 가끔 발생합니다.

  1. 캐시 시스템을 사용하는데, 이 놈이 Max 값으로 올라간 후 내려오지 않아요 (분명 Cache Entry 는 expires가 되어 메모리에서 해제된 것을 확인 했는데도)
  2. RDBMS 등에서 미리 여유분으로 잡아 먹고 있어요.
  3. 자주 사용하지 않는 시스템이 한번 실행 된 후 메모리를 반환하지 않아요

뭐 더 많은 상황이 있겠지만, 제가 간접적으로 겪은 1번 상황에 대해서만 얘기하겠습니다. 2번은 성능을 위해서라도 그냥 냅두시는 게 좋을 것이고, 3번은 1번에 묻어서 같이 해결 보는 걸로 하겠습니다.

자 그럼 우선 윈도우즈의 메모리 관리에 대해 알아봐야겠지요? 윈도우즈 OS 라는 놈이 메모리 관리에 대해서 그리 좋은 시스템이 못 되는 것은 유명합니다만, 그래도 쓸만은 합니다. 즉 특수한 극한 상황이 아니라면, 훌륭한 역할을 수행하고 있다는 얘기지요.

다만 메모리를 많이 쓰는 프로세스가 많은 일을 하고자 할 때, 메모리를 미리 선점한 놈들에게 정리 시키도록 해주면 훨씬 좋은 성능의 시스템이 될 수 있습니다.

위의 1번의 경우처럼 캐시시스템은 자신이 사용할 메모리를 예측하여, 미리 할당해서 사용하고, 메모리 사용을 더 이상 할 필요가 없어도, 향후 또 필요할 것을 대비해서 그냥 잡아둡니다. 그게 캐시 시스템 입장에서는 더 효과적이죠. 메모리를 반환하고, 필요할 때 다시 할당하는 일은 2중의 비용이 들어가니까요. (캐시 시스템 만든 개발자들이 똑똑하게 만들었겠죠) 다만 Memcached 나 SharedCache 처럼 메모리만을 기반으로 하는 캐시 시스템의 경우, 특별한 상황에서는 과도한 메모리를 사용하여, 운영자의 간담을 서늘케 하는 경우가 가끔 있습니다. (우린 이런 사람들을 새가슴 혹은 원리를 모르는 사람 이라고 하지요^^ – 농담입니다.)

다만 1번 경우 때문에 운영서버를 하루에 한번씩 RESET 하는 회사가 있어서요… 참 답답할 노릇이죠…

자 그럼 이런 상황에서 강제로 메모리를 반환 받을 수는 없을까요? OS 라면 가능하겠지요? OS가 대빵인데, 지들이 무슨 힘이 있겠어요?

자 여기서 보면 그럼 OS가 효율적으로 메모리 관리를 하면 1번과 같은 문제가 안 생기겠네요? 네 대부분 안 생깁니다. 다만 급격하게 메모리를 많이 사용해야 하는 프로세스가 늘어나면, Pagefile을 써야하고, 그럼 실행속도가 느려집니다. 이때서야 OS가 아… 너 메모리가 많이 부족하구나… 다른 놈들 메모리 좀 정리해서 방 비워줄께…

즉 뒷북이란 말이죠…

그럼 처음으로 돌아가서 메모리 관리용 Freeware를 사용하면 되잖아요… 운영지침상 서버에는 깔지 못한다니까요^^

그럼 어떻하지요? OS가 방을 비워주기를 기다리지 말고, 메모리 관리 Freeware 처럼 내 프로그램에서 OS에게 실행중인 프로세스들에게 사용하지 않는 메모리 비워라!!! 라고 요청할 수 있으면 되겠지요?

말이 참 길었죠? 실제 메모리를 반환하도록 하는 코드입니다.

public static class ProcessTool
{
#region << logger >>

private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
private static readonly bool IsDebugEnabled = log.IsDebugEnabled;

#endregion

/// <summary>
///
시스템에서 실행중인 모든 프로세스에 대해, 사용하지 않는 WorkingSet 메모리를 OS에게 반환하도록 합니다.
/// </summary>
/// <param name="excludeThisProcess">
현재 프로세스를 제외할 것인가 여부 (기본값은 제외)</param>
/// <param name="excludeProcessNames">
메모리 반환을 하지 않을 프로세스 명의 컬렉션</param>
public static void TrimAllProcessMemory(bool excludeThisProcess = true, string[] excludeProcessNames = null)
{
if(log.IsInfoEnabled)
log.Info("컴퓨터의 모든 프로세스에 대해 사용하지 않는 메모리를 OS에 반환하도록 합니다...");

var currentProcess = Process.GetCurrentProcess();

Parallel.ForEach(Process.GetProcesses(),
process =>
{
if(excludeThisProcess && (process.ProcessName == currentProcess.ProcessName))
return;

if(excludeProcessNames != null &&
excludeProcessNames.
Any(procName => procName == process.ProcessName))
return;

TrimProcessMemory(process);
});
}

/// <summary>
///
지정된 프로세스의 사용하지 않는 WorkingSet 메모리를 OS에게 반환하도록 합니다.
/// </summary>
/// <param name="process">
메모리 해제를 할 프로세스</param>
/// <returns>
메모리 해제 여부</returns>
public static bool TrimProcessMemory(Process process)
{
if(IsDebugEnabled)
log.Debug("프로세스의 Working Memory 중에 사용하지 않는 부분을 OS에 반환하도록 합니다.");

if(process == null)
return false;

bool _result;

try
{
long oldWorkingSet64 = process.WorkingSet64;
_result =
EmptyWorkingSet((long) process.Handle);

var targetProcess = Process.GetProcessById(process.Id);

if(_result)
{
if(log.IsInfoEnabled)
log.Info("프로세스[{0}]의 WorkingSet 메모리를 비웠습니다. 기존=[{1}], 현재=[{2}], 반환값=[{3}]",
process.
ProcessName, oldWorkingSet64, targetProcess.WorkingSet64, oldWorkingSet64 -
}
}
catch(Exception ex)
{
if(log.IsWarnEnabled)
{
log.Warn("Process[{0}]의 메모리를 정리하는데 예외가 발생했습니다...", process.ProcessName);
log.Warn(ex);
}
_result =
false;
}

return _result;
}

[
DllImport("psapi")]
internal static extern bool EmptyWorkingSet(long hProcess);
}




핵심은 psapi.dll  에 있는 EmptyWorkingSet(long hProcess) 입니다. 이 놈이 특정 프로세스의 사용하지 않는 메모리를 반환하게끔 합니다.



혹시 Win32 API 사용에 어려움이 있으시다면, PInvoke.net 사이트를 참조하세요. .NET에서 Win32 API 를 사용할 때, 많은 도움을 줄 수 있는 사이트입니다.



저는 위의 ProcessTool .TrimAllProcessMemory()  를 CPU 활용률이 5% 미만일 경우 1시간마다 실행하게끔 웹 어플리케이션에서 Background Service로 돌립니다. 그럼 운영자는 메모리를 별로 사용하지 않는데도 잘 돌아간다고 좋아합니다^^

2012년 1월 23일 월요일

Resharper 가 너무 느려요.

Resharper 가 상당히 좋은 개발 툴임에도 불구하고, 많은 닷넷 개발자에게는 그림이 떡 또는 가까이 하기엔 먼 당신이 되는 건 왜일까요?
우선 전 Resharper 를 4.x 때부터 사용해 왔으며, Resharper 없이는 개발을 못할 정도로 의존을 많이 하고 있습니다. 그만큼 저는 Resharper를 사용하는데 문제가 없습니다.
자 그럼 일반적으로 Resharper 가 느려서 쓰지 못하겠다고 하는 상황과 제의 개발 상황을 비교해 보시면 답이 어느 정도 나옵니다.
저는 다음과 같은 환경에서 Resharper를 씁니다.
  1. Class Library 개발을 주로 한다.
  2. 한 솔루션에 80여개의 프로젝트가 있다. (물론 Class 수에 따라 많이 다르다) (여기에는 Sample용 웹 Application 도 있다)
  3. Temp 폴더를 물리적으로 다른 폴더에 둔고, Resharper 파일들을 거기에 둔다.
  4. 메모리는 예전에는 4GB, 지금은 8GB를 사용, HDD 를 SSD를 사용한다.
자 이런 환경인데도, Visual Studio .NET 2010은 태생적으로 무거운데, 거기다가 확장 프로그램도 깔고, Resharper 도 구동하게 되면 상당히 부하가 걸립니다.
특히 코드 페이지에서 부하가 많이 걸리는 데, 이는 대부분 Intellisense 때문이다. 여기다가 Visual Studio 확장 툴 중에 Productivity Power Tool 기능을 같이 쓰게 되면, 더욱 느려지게 된다. (우선 이 확장 프로그램의 기능을 최소화 한 다음에 써보기 바란다.)
그 다음으로 아래 그림처럼 Resharper 의 Intellisense 기능 중에 C#, Javascript 만 두고 나머지는 제외 한다.
Resharper_Interllisense
HTML, CSS 등은 이미지 등의 리소스 들을 경로를 읽어드리고, 캐시해야 하기 때문에 속도가 느려지는 것입니다.
웹 개발자의 경우는 이와 같이 HTML, CSS 등의 Intellisense는 포기하고 해보시기 바랍니다. 쩝…
예전 버전에서는 웹 Application의 경우 이미지, CSS, Javascript 등의 리소스들의 경로 및 캐싱을 수행하는데, 프로젝트에서 제외하는 방법을 사용했는데, 위의 그림처럼 Intellisense에서 분야별로 선택해서 사용하면 좀 더 쾌적한 화경에서 Resharper를 사용하실 수 있을 것입니다.

2012년 1월 22일 일요일

Facebook에 NHibernate Group을 만들었습니다.

안녕하세요^^ 블로그로도 NHibernate 정보를 제공하기도 했는데, Facebook에 Group 기능이 있더군요. 이를 이용해서 Facebook에 NHibernate 그룹을 만들었습니다.

http://www.facebook.com/#!/groups/nhibernate.korea/

제가 관리하고 있고요, 신청하시는 분들은 모두 가입되도록 하겠습니다. 관심 있으신 분은 참여해주기 바랍니다.

한가지 더 – Google+ 에도 NHibernate Korea 서클을 만들었습니다.
둘 중 어떤 서비스가 더 좋을 지 몰라 우선 둘 다 만들어서 써보면서, 좋은 쪽으로 단일화해야 할 것 같습니다.

2012년 1월 14일 토요일

Visual Studio 11 Dev Preview를 위한 Resharper

Visual Studio 2010의 느려터진 속도에 절망의 세월을 보내고 있습니다만, 갑자기 Windows 8 Preview 와 더불어 Visual Studio 11 Dev Preview가 나와서 당장 설치해 봤습니다.
내부적으로는 .NET 4.5 기반이지만 .NET 4.0 에 설치되는 것을 보니, 버전 숫자에 의아하기도 하기도 하지만, 버전 구분을 자꾸 바꾸는 것이 좋지 않음을 경험으로 알고 있어서… “다행이다~” 를 외쳤습니다.

다음으로는 Visual Studio 11 을 실행하는 데 “우와” 엄청 빠르다… VS.NET 2010을 그냥 버리고 싶습니다…

그런데 한가지 제약이 있군요… 전 다른 건 몰라도 Resharper 가 없으면 코딩을 못합니다.
Resharper 의 조언이 없으면 불안하고, 색상이 달라지면 괜히 속성과 클래스가 헷갈리고 그렇습니다. ㅎㅎ

다행히 Resharper EAP 에서 Resharper 6.1.1 부터는 Visual Studio 11 Preview 도 지원하는군요.
다만 설치본이 아니라, 아래 화면처럼 Resharper for VS11 (.vsix) 를 다운 받으셔야 합니다.

Resharper_VS11_Download

설치 후 Visual Studio 11을 실행 시켰습니다… 결론적으로 Preview 임에도 Visual Studio 2010 보다 실행속도도 빠르고, 반응 속도도 빠르네요. 물론 영어와 한글버전의 차이도 있으려나 싶지만, 그래도 그렇지 Preview 가 더 빠르다는 게… 좀 그렇네요…

이제 저는 Visual Studio 11 Preview를 이용해 코딩합니다^^
Visual Studio 11 Dev Preview를 설치하신 분들은 한번 시도해보시길…

2012년 1월 13일 금요일

요즘 Issue 가 되는 빅데이터 분석에 대한 생각

지인이 빅데이터 분석 회사의 사장이고, 요즘 여러 매체에서도 “빅데이터” 라는 용어가 상당히 자주 등장하네요. 예전 Data Warehouse 나 ETL, OLAP 등의 용어가 이제는 너무 오래된 구식 용어가 된 느낌이네요^^

어쨌거나 “빅데이터” 라는게 직적적으로는 단순히 아주 많은 데이터를 의미하기도 하지만,

  • 얼마나 많은 데이터를 빠르고, 안정적으로 수집하고 관리하느냐
  • 원하는 분석 결과를 얼마나 효과적으로 추출할 수 있느냐?
  • 원하는 분석을 정의하기, 데이터 필터링 기능 등의 데이터 정제 기능
  • 분석 결과 리포팅 등의 보고서 기능

등을 필요로 하겠지요.

저야 이 분야에 대해, 아직까지는 DW 와 OLAP 수준을 벗어나지 못했습니다. 다만, 데이터 양이 기하급수적으로 늘었으니, 새로운 방법으로 데이터를 처리해야 하는 것에 이견이 있는 것이 아닙니다.

예전이나 지금이나 아주 많은 Data가 있더라도, 거기에서 의미있는 가설을 이용하여 의미있는 결과를 만들어 낼 수 있는 능력이 더 중요하다고 볼 수 있습니다.

그런 의미에서 제가 한 일 중에 기업의 모든 단위업무를 어떤 “고리” 를 이용하여, 업무들의 연속 흐름 즉 프로세스로 도출해 내는 Process Mining 도 여기에 해당합니다.

많은 데이타가 있을 수록 더 좋은 결과를 낼 수 있다고 생각할 수 있지만, 원하는 결과에 실제로 필요 없는 대량의 쓰레기 데이터는 그냥 쓰레기일 뿐이죠.

프로세스 시뮬레이터도 수 많은 Raw Data 를 생성하고, 이를 이용하여, 프로세스의 성능이나 적정 투입 리소스를 예측할 수 있습니다. 다만, 이 것도 목적에 따라, 기법에 따라 상당히 다른 결과를 산출합니다. 그걸 해석하고, 분석할 수 있는 능력이 중요하지요.

요즘 이슈가 되는 빅데이터는 이러한 기존 분석 방법을 뛰어넘는 것은 아니라 봅니다. Data를 다루기 위한 기법이 달라지고, 연산을 더 빠르고 하기 위한 알고리즘 등의 개선은 있어야 겠지만…

그리고, 요즘 빅데이터가 크기만을 뜻하는 게 아니라, 다양한 데이터 소스와 다양한 데이터 형식 (글, 이미지, 음성, 음악, 동영상 등) 를 뜻하기도 하니, 확실히 예전 DW 나 OLAP 하고는 다르지요.

전통적으로 데이터 분석에 유명한 SAS의 본부장이 쓴 글을 보면, 경계와 함께 데이터 분석의 중요한 점이 무엇인지 생각해 보게 합니다.

원문 : 빅데이터 분석, 자신감만으로 되나

2012년 1월 10일 화요일

최근 읽은 글 중 마음에 꽂힌 글들…


2012년 새해가 밝았습니다^^ 모든 분들이 새해에도 건강하시고, 하시는 일 잘 되시길 바랍니다.
물론 저도 잘되기 위해서 불철주야(야는 모르겠네요^^) 노력하려고 합니다.
자 그럼 제목에도 있듯이 요즘 제가 인터넷에서 읽은 글들 중 마음에 꽂힌 글 들을 링크 걸어봅니다.
더 많은 글들이 있지만, 그래도 한번쯤은 곱씹어야 할 글들인 거 같아 기록해 봅니다.
저도 올해는 좋은 성과를 내기 위해 스마트하게 일해야겠습니다^^