2014-12-09 2 views
1

이전 웹 사이트에서 CPU 사용량이 높은 이유를 디버깅하려고하고 DebugDiag의 일부 분석을보고 LOH 및 이후 GC에있는 개체의 양 컬렉션이 이유 일 수 있습니다. 하나의 .dbg 파일에서 우리는 ~ 3.5GB의 LOH를 가지고 있는데, 대부분의 객체는 문자열입니다.Large Object Heap에 추가 된 개체

개체가 LOH로 이동하려면 85000 바이트 이상이어야합니다.

이것이 예를 들어 단일 배열과 관련되어 있는지 확실하지 않은 내용입니다. 아니면 대형 객체 그래프를 참조 할 수 있습니까?

내가 말하고자하는 것은 객체 Foo가 있고 그 안에 n 개의 객체가 각각 포함되어있는 n 개의 다른 객체가 포함되어있는 것입니다. 이러한 각 객체에 문자열이 포함되어 있고 Foo (및 모든 하위 객체)의 총 크기가 85000 바이트보다 큰 경우 Foo는 LOH? 또는 Foo 객체 그래프의 어딘가에 85000 바이트 이상의 단일 배열이 있다면 LOH에 배치 된 배열일까요?

감사합니다.

+0

추측 : 웹 사이트에서 문자열을 연결하여 즉석에서 페이지/HTML을 생성하는 경우 StringBuilder로 전환하거나 적절한 컨트롤/데이터 바인딩으로 전환하는 것이 좋습니다. WinDbg는 그 문자열이 어디서 오는지 알아낼 수 있습니다. –

답변

4

어레이가 85000보다 큰 경우 전체 오브젝트가 아닌 LOH로 간주됩니다. 이것을 여기서 설명하기 위해 예를 만들었습니다.

class Program 
    { 
     static void Main(string[] args) 
     { 
      Obj o = new Obj(); 
      o.Allocate(85000); 
      Console.WriteLine(System.GC.GetGeneration(o)); 
      Console.WriteLine(System.GC.GetGeneration(o.items)); 
      Console.WriteLine(System.GC.GetGeneration(o.items2)); 
      Console.WriteLine(System.GC.GetGeneration(o.Data)); 
      Console.ReadLine();   
     } 

     class Obj 
     { 
      public byte[] items = null; 

      public byte[] items2 = null; 

      public string Data = string.Empty; 

      public void Allocate(int i) 
      { 
       items = new byte[i]; 
       items2 = new byte[10]; 
       Data = System.Text.Encoding.UTF8.GetString(items); 
      } 
     } 
    } 

여기에 문자열 데이터가있는 경우 문자열이 문자 배열이므로 LOH로 간주됩니다. Items2는 LOH가 아니며 항목은 LOH이지만 실제 오브젝트 o는 LOH가 아닙니다.

+0

좋은 답변입니다. 감사.이제 왜 LOH에 1GB 이상의 문자열이 있는지 찾아보십시오! 그런 기쁨을 디버깅하지 않습니다 :) –

1

85,000 바이트보다 큰 개별 개체 만 LOH에 저장됩니다. 오브젝트 그래프는 개별 오브젝트가 한계를 넘지 않는 한 LOH에 포함되지 않고 더 합계 할 수 있습니다. 바이트 배열과 문자열이 가장 일반적인 범인입니다.

0

@daspek 및 @dotnetstep에 동의합니다.

예를 들어, @ dotnetstep의 예에서 o의 크기는 32 비트 시스템에서는 12 바이트이고 64 비트 시스템에서는 24 바이트입니다.

Obj 클래스에 정의 된 모든 필드는 참조 유형이므로 모든 Obj 저장소는 자식 요소 (이 경우 배열)가 생성되는 힙 위치에 대한 포인터입니다.

이제 각각의 객체는 배열 (char [] 배열 임)이므로 85,000 바이트의 한계를 초과하면 LOH에 배치 될 수 있습니다.

정규 개체를 만들 때마다 LOH에 배치 할 수있는 유일한 방법은 모든 필드가 인 경우 32 비트 컴퓨터에 21251 개 이상의 필드가 있고 64 비트 컴퓨터에서 10626 개 이상의 필드가있는 경우입니다 참조 유형. 모든 의도와 목적을 위해, 그것은 일반적으로 실용적인 종류의 클래스 생성이 아닙니다. 그러한 수업을 접하는 것은 극히 드뭅니다.

포함 된 필드가 구조체 인 경우에는 클래스 정의의 일부로 간주됩니다. 따라서 4 바이트 힙 주소를 보유하는 대신 구조체의 내용은 클래스의 레이아웃에 포함됩니다. 큰 구조체가있는 필드의 수가 많으면 빠르게 85000 바이트의 한도를 얻을 수는 없지만 여전히 위반 될 수 있습니다.

관련 문제