Почему в приложении C # появляется исключение нехватки памяти?

Моя память физическая 4G, но почему у меня не хватает памяти, даже если я создаю только 1,5G объект памяти. Есть идеи почему? (В то же время я видел, что во вкладке «Быстродействие» диспетчера задач память не заполнена полностью, и я также мог бы здесь напечатать - так что памяти на самом деле не мало, поэтому я думаю, что столкнулся с некоторыми другими ограничениями памяти)?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestBigMemoryv1
{
    class MemoryHolderFoo
    {
        static Random seed = new Random();
        public Int32 holder1;
        public Int32 holder2;
        public Int64 holder3;

        public MemoryHolderFoo()
        {
            // prevent from optimized out
            holder1 = (Int32)seed.NextDouble();
            holder2 = (Int32)seed.NextDouble();
            holder3 = (Int64)seed.NextDouble();
        }
    }

    class Program
    {
        static int MemoryThreshold = 1500; //M
        static void Main(string[] args)
        {
            int persize = 16;
            int number = MemoryThreshold * 1000 * 1000/ persize;
            MemoryHolderFoo[] pool = new MemoryHolderFoo[number];
            for (int i = 0; i < number; i++)
            {
                pool[i] = new MemoryHolderFoo();
                if (i % 10000 == 0)
                {
                    Console.Write(".");
                }
            }

            return;
        }
    }
}
29
задан 07.10.2019, 16:35

5 ответов

В нормальном приложении Windows на 32 бита процесс только имеет 2 ГБ адресуемой памяти. Это не важно на сумму физической памяти, которая доступна.

Так доступные 2 ГБ, но 1.5 макс., которое можно выделить. Ключ - то, что Ваш код не является единственным кодом, работающим в процессе. Другие.5 ГБ являются, вероятно, CLR плюс фрагментация в процессе.

Обновление: в.Net 4.5 в процессе на 64 бита у Вас могут быть большие массивы, если установка gcAllowVeryLargeObjects включена:

На 64-разрядных платформах, включает массивы, которые больше, чем 2 гигабайта (ГБ) в общем размере. Максимальное число элементов в массиве является UInt32. MaxValue.

<configuration>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true" />
  </runtime>
</configuration>
40
ответ дан 07.10.2019, 16:39
  • 1
    I' ll смотрят на DataMapper. Спасибо за пример кода. – Chris Collins 24.04.2009, 21:41
  • 2
    Нет, каждый процесс получает полностью адресуемый 2 ГБ пространства виртуальной памяти. – Nick 07.10.2019, 16:39
  • 3
    Ник правилен. Каждый process' s адресное пространство независимо от anothers. Если они не принимают решение баловаться совместно используемой памятью. – JaredPar 07.10.2019, 16:40
  • 4
    Я сделал больше исследования один. Я причина, почему есть ограничение в 32-битной системе, состоит в том, потому что прикладная память доступа при помощи виртуального адреса, даже если у нас могли бы быть больше, чем 4G физическая память, но фактический корень limitaiton адресное пространство виртуальной памяти, правильное? – George2 07.10.2019, 16:40
  • 5
    @George2, который правилен – JaredPar 07.10.2019, 16:40
  • 6
    .5GB, может также быть все остальное работающее на машине это isn' t O/S комплектующие. – Robert C. Barth 07.10.2019, 16:40

На 32-разрядной операционной системе Windows максимальная память 'непривилегированного режима', к которой может получить доступ отдельное приложение, составляет 2 ГБ... предполагающих, что у Вас есть 4 ГБ памяти на поле.

Неуправляемый VC ++ Application' s потребление памяти на windows server

http://blogs.technet.com/markrussinovich/archive/2008/07/21/3092070.aspx

(Это забавно, Вы спросили это, потому что я спросил почти то же самое вчера...)

3
ответ дан 07.10.2019, 16:36
  • 1
    Спасибо uzbones, очень хороший документ! – George2 07.10.2019, 16:36
  • 2
    Да, в 32-битной системе, чтобы получить доступ к больше, чем 4G памяти (2G пользовательский способ и 2G система) операционная система должна была бы использовать что-то большее, чем 32-битный интервал для индекса. Вы можете обойти это при помощи AppDomains en.csharp-online.net/… – uzbones 07.10.2019, 16:36
  • 3
    Привет uzbones, это означает 4G, память бесполезна? Мое заявление могло только потреблять максимум 2G? – George2 07.10.2019, 16:37
  • 4
    Я сделал больше исследования один. Я причина, почему есть ограничение в 32-битной системе, состоит в том, потому что прикладная память доступа при помощи виртуального адреса, даже если у нас могли бы быть больше, чем 4G физическая память, но фактический корень limitaiton адресное пространство виртуальной памяти, правильное? – George2 07.10.2019, 16:37
  • 5
    Хорошо... не, при наличии больше, чем 4G памяти, Вы могли управлять двумя копиями Вас программа каждое потребление 2G памяти каждый. И поскольку KristoferA упоминает далее ниже есть системный выключатель, который может быть сделан, чтобы изменить сумму на 3G, или Вы должны пойти 64 бита. – uzbones 07.10.2019, 16:38

У Вас есть макс. из адресуемой памяти на 2 ГБ как приложение на 32 бита как другие упомянутые плакаты. Не забывайте об издержках. Вы создаете массив 93 миллионов объектов - если, оказывается, существует 4 байта издержек на объект, это составляет дополнительные 350 МБ памяти.

4
ответ дан 07.10.2019, 16:37
  • 1
    потребуйте ' data_mapper' – Jeremy 03.12.2013, 23:44
  • 2
    Да, в значительной степени. Все Ваши указатели сохранены в 4 байтах, который устанавливает предел того, сколько они видят. Вещами была еще худшая спина в эпоху 16-битных указателей. Не спрашивайте меня о segment:offset или работе с окнами высокая память... – geofftnz 07.10.2019, 16:38
  • 3
    Прохладный, geofftnz спасибо! – George2 07.10.2019, 16:38
  • 4
    Я сделал больше исследования один. Я причина, почему есть ограничение в 32-битной системе, состоит в том, потому что прикладная память доступа при помощи виртуального адреса, даже если у нас могли бы быть больше, чем 4G физическая память, но фактический корень limitaiton адресное пространство виртуальной памяти, правильное? – George2 07.10.2019, 16:39

Просто дополнительный к другим точкам; если Вы хотите получить доступ к грязному объему памяти, рассматриваете x64 - но знаете, что максимум единственный размер объекта - все еще 2 ГБ. И потому что ссылки больше в x64, это означает, что Вы на самом деле становитесь меньшими максимальный размер массива/списка для ссылочных типов. Конечно, к тому времени, когда Вы поражаете тот предел, Вы, вероятно, делаете вещи неправильно так или иначе!

Другие опции:

  • файлы использования
  • используют базу данных

(очевидно, у обоих есть различие в производительности по сравнению с незавершенной памятью)

<час>

Обновление: В версиях.NET до 4,5, максимальный размер объекта составляет 2 ГБ. От 4,5 вперед можно выделить большие объекты, если gcAllowVeryLargeObjects включен. Обратите внимание, что предел для string не затронут, но "массивы" должны покрыть "списки" также, так как списки поддерживаются массивами.

10
ответ дан 07.10.2019, 16:38
  • 1
    когда Вы используете ' DataMapper.setup (: значение по умолчанию, " sqlite3:: memory") ' это - дб im-памяти? Как Вы сохранили бы это к диску, или как Вы откроете существующий sqlite файл дб? – LoveMeSomeCode 25.08.2010, 20:06
  • 2
    Сам Windows накладывает 2gb/3gb ограничение за процесс на win32. Теоретический лимит с 32-битными ссылками составляет 4 ГБ. Win64 уносит оба из этих ограничений из воды. – Marc Gravell♦ 07.10.2019, 16:39
  • 3
    Когда Вы говорите макс., что единственный объект - Вы говорящий об объектах CLR или сыром размере распределения (местный житель или управляемый). Я предполагаю, что первый, но требуемый проверяет. Также сделайте у Вас есть ссылка для этого, я hadn' t замеченный это все же. Can' t воображают, почему Вы хотели бы превысить 2 ГБ хотя для единственного объекта. – JaredPar 07.10.2019, 16:39
  • 4
    1. " знайте, что максимальный единственный размер объекта все еще 2GB" - Марк, у Вас есть документы, чтобы доказать этот отчет? Мне особенно интересно, в каких средствах единственный объект, поскольку мы можем соединение возражать, чтобы сформировать новые объекты, поэтому что означает единственный объект в Вашем контексте? – George2 07.10.2019, 16:40
  • 5
    1. Как делают Вы получаете заключение - " это означает, что Вы на самом деле получаете меньший максимальный размер множества/списка для reference-types." от " потому что ссылки больше в x64"? Вы могли предоставить больше подробную информацию, пожалуйста? – George2 07.10.2019, 16:40
  • 6
    Я сделал больше исследования один. Я причина, почему есть ограничение в 32-битной системе, состоит в том, потому что прикладная память доступа при помощи виртуального адреса, даже если у нас могли бы быть больше, чем 4G физическая память, но фактический корень limitaiton адресное пространство виртуальной памяти, правильное? – George2 07.10.2019, 16:41

Только добавить к предыдущим ответам: можно пойти вне предела на 2 ГБ на системы, загруженные с/3Gb [и дополнительно userva] флаги начальной загрузки.

5
ответ дан 07.10.2019, 16:40
  • 1
    DataMapper.setup(:default, "sqlite3:path/to/db/file.db") – Bob Aman 26.08.2010, 20:11
  • 2
    Хотя использовать выключатель/3Gb, Вы должны будете изменить исполняемый файл, чтобы вручную установить флаг в нем, чтобы он был в состоянии использовать в своих интересах флаг ботинка. – uzbones 07.10.2019, 16:40
  • 3
    Я сделал больше исследования один. Я причина, почему есть ограничение в 32-битной системе, состоит в том, потому что прикладная память доступа при помощи виртуального адреса, даже если у нас могли бы быть больше, чем 4G физическая память, но фактический корень limitaiton адресное пространство виртуальной памяти, правильное? – George2 07.10.2019, 16:40

Теги

Похожие вопросы