2009-04-02 4 views
5

엔터티 프레임 워크는 새 개체를 데이터베이스에 삽입 할 때 과도한 양의 메모리를 사용합니다.엔터티 프레임 워크 메모리 사용량

for(int i = 0; i < numOwners; ++i) 
{ 
    var owner = Owner.CreateOwner(); 
    db.AddToOwnerSet(owner); 
    for(int j = 0; j < numChildren; ++j) 
    { 
     var child = Child.CreateChild(); 
     owner.Childs.Add(child); 
    } 
} 
db.SaveChanges(); 

이 시점에서 이러한 개체에는 데이터 요소가 거의 없습니다. 이러한 개체를 데이터베이스에 140,000 개를 삽입 할 때 응용 프로그램의 총 메모리 사용량은 600 MB 였고 300,000 개에 대해 1.2 기가 바이트였습니다. 이 객체는 작고 문자열 이름과 정수 키입니다.

SaveChanges 호출을 루프에 넣음으로써 메모리 사용량을 줄일 수 있지만 실행 시간이 훨씬 나 빠지며 이미 상당히 나 빠졌습니다.

엔티티 프레임 워크가 많은 메모리를 사용하는 이유 또는 메모리를 적게 사용하는 방법을 아는 사람이 있습니까?

답변

2

엔터티 프레임 워크는 많은 ORM과 마찬가지로 데이터를 메모리에 유지하므로 많은 메모리 내 컬렉션과 마찬가지로 내부 배열이있을 수 있습니다. 컬렉션에 항목을 추가하면 내부 배열의 용량이 두 배가됩니다.

예를 들어, 256 개 항목을 포함하는 ArrayList와 같은 콜렉션이 있고 그 중 257 번째 항목을 추가하면 내부적으로 512 개의 항목 배열에 대해 새로운 메모리 블록이 할당됩니다. 새 512 항목 배열에 복사 한 다음 256 항목 배열을 가비지 수집에 사용할 수있게합니다. 따라서 전환 시점에 257 번째 항목을 추가했기 때문에 768 개의 항목이 메모리에 할당됩니다. memorystream을 사용할 때 나는 두통을 겪었습니다. 왜냐하면 당신이 정말로 필요로하는 것보다 거의 3 배나 많은 연속되지 않은 메모리를 필요로하기 때문입니다. 이것은 컬렉션에 표시되는 .Capacity 속성이며, 거의 항상 2의 제곱입니다 (필요에 따라 크기가 두 배이기 때문에).

내 생각에 메모리 개체 모음을 지원하는 데 필요한 크기의 두 배 크기의 내부 배열이 있습니다. 따라서 같은 유형의 300,000 개의 객체가 524,288 크기의 내부 배열로 유지 될 수 있습니다. 또한 .NEt Framework의 다른 기술과 비슷한 기술이라면 262145 항목이 추가 될 때마다 항목이 새 배열에 복사되는 동안 262144 및 524288 배열이 메모리에 존재합니다. 총 786432 개의 항목이 메모리에 있습니다. 이전 배열은 가비지 수집기가 더 이상 필요하지 않다고 결정할 때까지 계속 머물러 있습니다.

사용할 수있는 동시성 지원과 관련하여 Entity 프레임 워크에서 메모리 사용을 향상시킬 수있는 옵션이있을 수 있습니다. 필자는 여기서 추측하고 있지만 동시성을 지원하기 위해 현재 버전의 데이터와 동시성을 지원하는 비교를위한 원래 버전을 모두 메모리에 저장합니다.

나는 또한 당신이 어떤 데이터와 상호 작용 하는지를 살펴볼 것입니다. 쿼리 된 내용과 메모리에로드 된 내용을 제한하는 현명한 기준을 찾아보십시오. 예를 들어 사용자가 고객 계정을 편집 할 수있는 응용 프로그램을 가지고 있지만 특정 계정 만 할당 된 경우이를 필터링 기준으로 사용하여 사용자가 잠재적으로 상호 작용할 수있는 계정 만 메모리에로드 할 수 있습니다.

1

개체는 실제 데이터면에서 "작을 수 있지만 각 개체는 DTO가 아닙니다. Entity Framework는 각 개체에 실제 코드의 크기가 큽니다. 즉, 각 개체의 실제 크기가 상당히 큽니다. 큰.

대형 개체 그래프를 지속적으로 사용하는 경우 안정적이고 성숙하며 작동이 입증 된 NHibernate와 같은 것을 사용하는 것이 좋습니다. Entity Framework는 기능 및 성능 측면에서 매우 뒤떨어져 있습니다.

2

나는 이것이 이전 질문이지만 오늘도 똑같은 문제를 겪고 있었고 그 원인을 발견 할 수 있었다.

SQL 스크립트를 생성하면 메모리가 크게 점프되는 것으로 보입니다. 스토어드 프로 시저를 만들고이를 객체에 연결한다는 것을 알았지 만 (this article에 나와있는 ID 값을 반환해야 함) 300MB 이상의 메모리를 절약 할 수있었습니다.

관련 문제