2013-08-11 2 views
4

최적화 문제에서 검색 속도를 높이기 위해 엄청난 수의 인스턴스를 생성하는 클래스 B가 있습니다. 번호가 너무 커서 OutOfMemory-Exceptions을 자주 생성합니다. 이 문제를 해결하기 위해 매 x 초마다 인스턴스 수를 줄이지 만 좀 더 합리적인 방법으로 작업하고 싶습니다. 이를 위해 내가 알고 싶습니다 : 어떻게가를 추정 할 수 있습니다클래스 인스턴스 수를 관리하십시오.

  1. 더 많은 기술 "살아"(창조 아직 쓰레기가 수집되지 않음) 인스턴스의 수를 관리 할 수있는 좋은 방법은 무엇입니까 RAM 내 인스턴스에 대해 절반 정도 사용해야합니까?

+0

나는 우리가 더 필요하다고 생각하면 memmory있어 관리 할 수를 인스턴스가 당신에게 도움이되는 정보. – OneFineDay

+0

그래프에 저장 가능한 비용 효율적인 경로가있는 나무가 많이 있습니다. 내 "클래스 B"는 해당 트리의 노드입니다. 비용 함수가 항상 변경됨에 따라 모든 트리가 항상 새로운 경로를 추가합니다. 이전 경로도 유용 할 수 있지만 설명 된 메모리 이유로 인해 일부는 지워 져야합니다. –

+1

'OutOfMemoryException'은 그리 흔한 일이 아니므로 잘못하고있는 일이 잘못되었음을 나타냅니다. 일부 코드가 도움이 될 수도 있습니다 –

답변

5

우선 모든 단일 개체의 메모리 사용 공간을 최대한 줄이려고합니다. 엄청난 수의 개체를 만들면 비슷한 속성을 공유하는 개체가 많아서 flyweight pattern의 완벽한 후보가됩니다. Wikipedia 기사에 따른 고전적인 예는 워드 프로세싱입니다.

플라이급 패턴의 전형적인 사용 예는 워드 프로세서에서 문자의 그래픽 표현을위한 데이터 구조입니다. 문서의 각 문자에 대해 글꼴 외곽선, 글꼴 메트릭 및 기타 서식 지정 데이터를 포함하는 글리프 개체를 가져 오는 것이 바람직 할 수 있지만 각 문자에 대해 수 백 또는 수천 바이트에이를 수 있습니다. 대신 모든 문자에 대해 문서의 동일한 문자의 모든 인스턴스에서 공유하는 플라이급 글리프 객체에 대한 참조가있을 수 있습니다. 문서 및/또는 페이지의 각 문자의 위치 만 내부적으로 저장해야합니다.

두 번째 단계로, 추정치 단일 개체의 크기입니다. 나는 실제 크기를 얻는 것이 not that easy in C#이기 때문에을 추정하는 을 강조한다. 이 추정치는 OutOfMemoryException을 만나지 않고도 안전하게 인스턴스화 할 수있는 객체의 최대 수인 N을 설정하는 데 사용될 수 있습니다.

개체가 생성되거나 소멸 될 때마다 개체 카운터를 업데이트하여 대략적으로 살아있는 개체 수를 추적하여이 정보를 활용할 수 있습니다. 스레드 안전성이 문제가되는 경우

class Foo { 

    private static NumberOfInstances = 0; 

    public Foo() { 
     NumberOfInstances++; 
    } 

    ~Foo() { 
     NumberOfInstances--; 
    } 
} 

,이 구현은 물론 조금 세련되어야 할 것이다.

편집 : 편집자 : mike z가 자신의 의견에서 지적했듯이, 파이널 라이저를 통해 이것을 구현하면이 상황에서 심한 performance problems이 발생할 수 있습니다.결과적으로 IDisposable을 구현하고 Dispose 작업에서 감소를 수행하는 것이 더 나을 것입니다. 그러나 이것은 객체를 폐기하는 것을 잊을 수 있다는 단점이 있습니다. 그러나 이것이 귀하의 경우에 심각한 문제가 될지는 의심 스럽습니다.

+1

소멸자가있는 개체는 메모리에서 제거하려면 적어도 2 GC주기가 필요하므로 심각한 성능 영향을 미칠 수 있습니다. –

2

나는 두 번째 질문에 대한 답을 모르겠지만, 첫 번째 질문에 대한 답이 될 수있다 :

0

각 노드 확장은 데이터를 쿼리해야하고 모든 객체 데이터를 메모리에 저장하지 않고 각 노드에 정의 매개 변수를 저장하기 만하면됩니다. 노드가 선택되면 쿼리의 데이터가 표시됩니다.

+0

나는 그것이 무엇을 의미하는지 모릅니다. –

+0

그래프의 데이터는 어디에서 왔습니까? 이 모든 데이터를 현재 노드에 저장하고 있습니까? – OneFineDay

+0

노드는 이전 및 다음 노드와 읽기 전용 데이터 객체에 대한 참조를 저장합니다. –

2

나중에 액세스 할 수 있도록 가능한 한 많은 계산 된 데이터를 유지하고 싶습니다. 아마도 .NET 4.0에 도입 된 MemoryCache 클래스가 도움이 될 수 있습니다.

당신은 같은 것을 할 수있는 :

var cache = new MemoryCache("PathCache", new NameValueCollection() 
{ 
    { "CacheMemoryLimitMegabytes", "256" }, // max 256 MB 
    { "PhysicalMemoryLimit", "50" } // max 50% of RAM 
}); 

// cache an item 
cache["MyPath"] = "..."; 

// check, whether the cache contains an item 
if (cache.Contains("MyPath")) 
{ 
    // cache hit! 
    var cachedPath = cache["MyPath"]; 
} 

// ensure cache is released somewhere in your code 
cache.Dispose(); 
0

당신은 당신의 인스턴스를 작성하는 팩토리 패턴을 활용 그래서 그들을 추적하고

관련 문제