문제

내가 하는 일부 프로젝트의 오일러 연습과적으로 시나리오를 나 원하는 배열이 큰 2,147,483,647(의 상한 int C#).

확실한 이들은 큰 배열을,그러나 인스턴스,저는 이것을 할 수 없

// fails
bool[] BigArray = new BigArray[2147483648];

// also fails, cannot convert uint to int
ArrayList BigArrayList = new ArrayList(2147483648); 

그래서 나는 더 큰 배열?

편집:그 체 Atkin, 에,당신은 알고,그래서 그냥 정말 큰 하나:D

도움이 되었습니까?

해결책

언제든지 당신은 작업으로 배열이 큰,당신은 아마도 더 나은 솔루션을 찾을하는 문제입니다.하지만 그는 말했다 나는 아직 시도는 당신의 질문에 대답합니다.

에서 언급했듯이 문서 거기에는 2GB 제한에는 어떤 물체에서.Net.에 대한 모든 x86,x64 및 IA64.

으로 32-비트 윈도우 운영 체제 시스템,있는 2 기가 바이트 제한에 크기의 객체를 만들 수 있습하는 동안 실행 관리되는 64 비트 응용 프로그램 에 64-비트 윈도우 운영 체제입니다.

또한 당신은 당신이 정말 배열을 너무 큰 스택에서 당신은 스택 오버플로우가 발생합니다.정의한 경우에는 배열에 힙,그것을 할당하려고합니다 그것은 모두 하나의 큰 지속적인 블록입니다.더 나은 것을 사용하 ArrayList 는 암시적 동적 할당에 힙.이것을 허용하지 않습니다 당신은 과거를 얻기 위해 2 기가바이트,하지만 아마을 얻을 수 있도록 가깝습니다.

내 생각에 스택 크기 제한될 것이 더 큰 경우에만 사용하고 있 64 또는 IA64 건축과 운영 체제입니다.를 사용하여 64 또는 IA64 당신이 64 비트 메모리를 할당할 수는 대신 32 비트입니다.

할 수 없는 경우에 할당 배열에 모든 목록을 한 번에 할 수 있는 아마 할당합니다.

배열을 사용하여 목록 추가 및 1 개체에서 시간에는 64Windows2008 년을 가진 기계 6GB RAM,가장를 얻을 수 있습 ArrayList 하는 크기:134217728.그래서 저는 정말로 생각을 찾을 수있는 더 나은 당신의 문제에 대한 해결책을 사용하지 않는 많은 메모리입니다.아마도 쓰는 대신에 파일을 사용하여 RAM.

다른 팁

배열 한계는 Afaik이며 64 비트에서도 Int32로 고정됩니다. 단일 객체의 최대 크기에 캡이 있습니다. 그러나, 당신은 아주 큰 들쭉날쭉 한 배열을 아주 쉽게 가질 수 있습니다.

더 나쁜; 참조는 x64에서 더 크기 때문에 실제로 얻을 수있는 ref- 타입 배열 더 적은 단일 배열의 요소.

보다 여기:

2.0 .NET 런타임의 64 비트 버전이 여전히 2GB로 제한된 배열 최대 크기를 가지고있는 이유에 대한 여러 쿼리를 받았습니다. 그것이 늦게 뜨거운 주제 인 것처럼 보인다는 것을 감안할 때 나는 약간의 배경을 생각 했고이 한계를 해결하기위한 옵션에 대한 토론은 순서대로 진행되었습니다.

먼저 일부 배경; 2.0 버전의 .NET Runtime (CLR)에서 우리는 64 비트 버전의 런타임에서도 GC 힙에 허용되는 최대 객체 크기를 2GB로 유지하기 위해 의식적인 설계 결정을 내 렸습니다. 이것은 32 비트 CLR의 현재 1.1 구현과 동일하지만, 가상 주소 공간이 너무 조각화되어 2GB를 현실적으로 찾을 수 없기 때문에 실제로 32 비트 CLR에 2GB 객체를 할당하는 데 실제로 압박을 가하기가 어려울 것입니다. 구멍. 일반적으로 사람들은 인스턴스화 될 때 (또는 어디에나)> 2GB가 될 유형을 작성하는 데 특히 관심이 없지만, 배열은 관리 된 힙 내에서 생성되는 특별한 종류의 관리 유형이기 때문에이 제한으로 어려움을 겪고 있습니다.


.NET 4.5에서 메모리 크기 한계는 선택적으로 다음으로 제거됩니다 gcallowverylargeobjects 그러나 플래그는 최대치를 변경하지 않습니다 치수 크기. 핵심 요점은 사용자 정의 유형 또는 다중 차원 배열 배열이있는 경우 이제 메모리 크기에서 2GB를 넘어갈 수 있다는 것입니다.

당신은 전혀 큰 배열이 필요하지 않습니다.

메소드가 자원 문제에 빠지면 리소스를 확장하는 방법을 보지 말고 방법을 살펴보십시오. :)

다음은 3MB 버퍼를 사용하여 Eratosthenes의 체를 사용하여 프라임을 계산하는 클래스입니다. 이 클래스는 Primes를 얼마나 멀리 계산했는지 추적하고 범위를 확장해야 할 때 3 백만 개의 숫자를 테스트하기 위해 버퍼를 생성합니다.

목록에 발견 된 소수를 유지하고 범위가 확장되면 Previos Primes는 버퍼의 숫자를 배제하는 데 사용됩니다.

나는 약간의 테스트를했고 약 3MB의 버퍼가 가장 효율적입니다.

public class Primes {

   private const int _blockSize = 3000000;

   private List<long> _primes;
   private long _next;

   public Primes() {
      _primes = new List<long>() { 2, 3, 5, 7, 11, 13, 17, 19 };
      _next = 23;
   }

   private void Expand() {
      bool[] sieve = new bool[_blockSize];
      foreach (long prime in _primes) {
         for (long i = ((_next + prime - 1L) / prime) * prime - _next;
            i < _blockSize; i += prime) {
            sieve[i] = true;
         }
      }
      for (int i = 0; i < _blockSize; i++) {
         if (!sieve[i]) {
            _primes.Add(_next);
            for (long j = i + _next; j < _blockSize; j += _next) {
               sieve[j] = true;
            }
         }
         _next++;
      }
   }

   public long this[int index] {
      get {
         if (index < 0) throw new IndexOutOfRangeException();
         while (index >= _primes.Count) {
            Expand();
         }
         return _primes[index];
      }
   }

   public bool IsPrime(long number) {
      while (_primes[_primes.Count - 1] < number) {
         Expand();
      }
      return _primes.BinarySearch(number) >= 0;
   }

}

나는 64 비트 CLR 내에도 물체 당 2GB (또는 아마도 1GB - 정확히 기억할 수 없음)의 한계가 있다고 생각합니다. 그러면 더 큰 배열을 만들지 못하게됩니다. Array.CreateInstance는 크기에 대한 Int32 인수 만 취한다는 사실도 암시 적입니다.

더 넓은 점에서, 나는 당신이 그 큰 배열이 필요한 경우, 당신이 문제에 접근하는 방식을 실제로 바꿔야한다고 생각합니다.

저는 C# (예 : 이번 주에 배우는 학습)의 초보자이므로 ArrayList가 구현되는 방법에 대한 정확한 세부 사항은 확실하지 않습니다. 그러나 ArrayList 예제에 대한 유형을 정의하지 않았으므로 배열은 객체 참조 배열로 할당 될 것이라고 생각합니다. 이것은 아키텍처에 따라 실제로 4-8GB의 메모리를 할당하고 있음을 의미 할 수 있습니다.

MSDN에 따르면, 바이트 배열에 대한 인덱스는 2147483591보다 클 수 없습니다. 4.5 이전 .NET의 경우 배열의 메모리 제한이기도합니다. .NET 4.5 에서이 최대 값은 동일하지만 다른 유형의 경우 최대 2146435071이 될 수 있습니다.

이것은 그림을위한 코드입니다.

    static void Main(string[] args)
    {
        // -----------------------------------------------
        // Pre .NET 4.5 or gcAllowVeryLargeObjects unset
        const int twoGig = 2147483591; // magic number from .NET

        var type = typeof(int);          // type to use
        var size = Marshal.SizeOf(type); // type size
        var num = twoGig / size;         // max element count

        var arr20 = Array.CreateInstance(type, num);
        var arr21 = new byte[num];

        // -----------------------------------------------
        // .NET 4.5 with x64 and gcAllowVeryLargeObjects set
        var arr451 = new byte[2147483591];
        var arr452 = Array.CreateInstance(typeof(int), 2146435071);
        var arr453 = new byte[2146435071]; // another magic number

        return;
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top