2010-05-27 3 views
2

ASP.NET과 DevExpress ASPxGridView 구성 요소를 사용하는 여러 프로젝트가 있습니다. 이 프로젝트의 개발 과정에서 데이터 바인딩에 대한 몇 가지 기술이 사용되었으며 이제이 프로젝트 중 일부가 서버의 모든 메모리를 차지하는 것으로 나타났습니다.ASP.NET 메모리 관리 기법

원래 우리는 저장 프로 시저를 호출하고 DataSet을 gridview에 바인딩했지만 DX 권장 사항에서는이를 ObjectDataSource로 수정하고 DB에 대해 Linq 문을 궁극적으로 사용하는 개체 및 개체를 만들고이를 반환합니다. 바인드되는 객체의 일반적인리스트.

불행히도이 문제는 현재 해결되지 않습니다. 우리는 여전히 많은 양의 메모리를 먹어 치우는 것을 눈치 채고 있습니다. 그리고 나는 이것의 바닥에 도달하려고 노력하고 있습니다. RedGate 메모리 프로파일 러를 실행할 때마다 그리드에 리 바인드 할 때마다 문자열, RuntimeTypeHandles 및 인스턴스의 인스턴스가 많이 생성됩니다.

DataBind는 페이지로드시에 수행되고 그리드는 정렬시 포스트 백을 사용하지만 모든 바인드에서 MBs 메모리 누수가 발생하므로 어떤 기술을 사용할 수 있는지/객체 관리에 대한 모범 사례가 궁금합니다. 우리가 통제 할 수있어? 데이터 객체에 IDisposable을 구현하고 linq 컨텍스트를 삭제하고 다른 객체를 null로 설정했지만 차이가없는 것 같습니다. 나는 모든 호출에서 데이터 객체의 인스턴스를 만드는 것처럼 보이고 심지어 dispose를 호출해도 아무런 차이가 없다.

+0

'누출'이라고 설명하십시오. 그 물체는 여전히 어떤 방식으로 도달 할 수 있습니까? 그렇지 않은 경우 GC에서 많은 양의 할당과로드가 누출되는 경우는 아닙니다. '# GC 컬렉션'에 대한 프로필을 작성 했습니까? –

+0

메가 바이트? 그건 몇 가지 표 ... 당신은 페이징을 제대로 사용하고 있습니까? 'LinqDataSource'를 사용하는 것이 쉽습니다. – Thorarin

+0

메모리 부족 예외 또는 다른 유형의 메모리 문제가 있습니까? 페이지를 백 또는 수천 번 실행하면 결국 메모리가 맨 위에 나오지 않거나 "나쁜 물건"이 발생합니까? 다른 말로하면, 메모리 사용이 정말로 해로운가요 아니면 그냥 정상입니까? ASPxGridViews를 사용하고 실제로이 문제가 없습니다. – Greg

답변

2

와우, 많은 배관 및 이동 부품이 있습니다.

조금 좁히는 것이 가능합니까? 즉, 페이지에서 물건을 떼어 내고 작동 방식을 확인할 수 있습니까?

용서하십시오. 그러나 '누출 기억'이라고 말하면 무엇을 의미하며 어떻게 알 수 있습니까? GC는 '게으른'것이며 그렇게 할 압력이있을 때까지 아무 것도하지 않습니다. 이것은 좋은 일이지만 컬렉션이 필요할 때까지는 메모리가 누적 된 것처럼 보일 수 있습니다. 그런 다음 메모리가 많이 확보 될 수 있습니다. 이러한 이유로 메모리 프로파일 러는 종종 톱니처럼 보입니다.

페이징 작업을 수행하기 위해 그리드 데이터를 어떻게 저장하고 있습니까? viewstate에서 데이터 집합이 유지되는 것을 보았습니다. 즉, 데이터가 그리드와 함께 클라이언트에 전달됨을 의미합니다. 포스트 백 (post-back) 페이지에서 다시 쿼리하는 경우 많은 공간을 낭비하게됩니다.

또 다른 공통적 인 문제는 대형 개체를 오래 동안 유지해야하는 이벤트 구독입니다. 저는 실제로 세션이 존재하는 한 페이지를 유지 한 상태로 데이터 그리드가 배치 된 코드를 보았습니다. 각 포스트 백에서 이런 일이 계속 반복해서 일어났습니다. 이 경우 개체가 실제로 '사용중'이기 때문에 GC가 도움이되지 못합니다.

정렬을 해제하고 제 3 자 컨트롤을 제거하고 더 작은 데이터 세트를 사용하는 등 간단한 방법을 시도하십시오. 메모리 프로파일러와 서버를 압박하는 것을 사용하여이 시나리오를 측정하십시오. '누출'이 없다면 물건을 다시 추가하여 헤이 와이어가 언제 나타나는지 확인하십시오.

+0

메모리가 누수 됨으로써 각 후속 페이지로드에서 새 개체가 생성된다는 것을 의미합니다. 생성 된 이전 인스턴스가 정리되지 않았습니다. Redgate Memory Profiler를 사용하고 있습니다. 페이지를로드하고 스냅 샷을 기준으로 사용합니다. 그런 다음 일종의 정렬을했는데 데이터 객체의 새 인스턴스가 두 개 생성되어 3 개의 라이브 인스턴스가 표시됩니다. 다른 열을 정렬하고 4 번째 인스턴스를 얻습니다. 우리는 세션 또는 viewstate에 그리드를 저장하지 않습니다. 우리는 단지 페이지로드시 그리드에 바인딩하고 있습니다. – Hammerstein

1

매번 iis 서버로 너무 많은 데이터를 전송할 수 있습니다. 표제와 함께 표준 linq 데이터 소스를 사용하거나 정렬, 페이징 또는 다른 콜백 콜백을 수행 할 때마다 전체 데이터가 메모리에로드 된 다음 정렬되고 페이징된다는 것을 기억하십시오.

이것은 매우 많은 양의 데이터를로드하는 경우 서버 메모리를 쉽게 낭비한다는 것을 의미합니다. 많은 사용자가 동일한 페이지를 열어서 각 사용자의 전체 데이터를 메모리에로드 할 것이며 GC에 모든 정보를 확보 할 시간이 없을 수도 있다고 생각하십시오.

DevExpress는 데이터 서버의 모든 페이징 및 정렬을 수행하는 LinqServerModeDataSource을 제공합니다.

사용할 수없는 경우 필터링하여 더 작은 데이터 집합을 검색하십시오.

+0

LinqServerModeDataSource Linq 컨텍스트 및 테이블 이름이 필요합니다. 내 개체가 Linq에서 직접 IQueryable을 반환하면 내 데이터를 사용할 수 있습니까? 아니면 ObjectDataSource에 보내는 목록을 페이징하도록 노력하고 있습니까? 그리드에 표시해야하는 일부 시스템의 데이터는 100,000+ 레코드 범위에 있으므로 메모리가 사라지는 원인을 분명히 이해할 수 있습니다. – Hammerstein