Pergunta

Eu estou querendo saber por que eu não sou capaz de alocar mais que 1.000 MB de memória no meu processo de .NET de 32 bits. A seguir mini-aplicativo lança uma OutOfMemoryException depois de ter alocado 1.000 MB. Por 1.000 MB, e não dizer de 1,8 GB? Existe um processo de ampla definição que eu poderia mudar?

static void Main(string[] args)
{
    ArrayList list = new ArrayList();
    int i = 0;
    while (true)
    {
        list.Add(new byte[1024 * 1024 * 10]); // 10 MB
        i += 10;
        Console.WriteLine(i);
    }
}

PS:. Coleta de lixo não ajuda

Editar, para esclarecer o que eu quero: Eu escrevi um aplicativo de servidor que lida com grandes quantidades de dados antes de escrever ao banco de dados / disco. Em vez de criar arquivos temporários para tudo, eu escrevi um cache na memória, o que torna a coisa toda super-rápido. Mas a memória é limitada, e por isso eu tentei descobrir quais são os limites. E se perguntou por que o meu pequeno programa de testes jogou a OutOfMemoryException depois de exatamente 1.000 MB.

Foi útil?

Solução

O limite de espaço de endereço virtual de um processo Win32 é de 1,5 GB (não é inteiramente verdade). Além disso nos quadros .NET há um limitador para a% de memória um processo .NET pode consumir. O Machine tem um elemento processModel com um memoryLimit atributo que representa a% de memória disponível um processo pode consumir. O valor padrão é de 60%.

Se a máquina estiver em execução no tem 2GB de memória ou você não tiver habilitado a opção / 3GB em sua BOOT.INI então você está indo para obter ~ 1,3 GB de memória por processo.

Não consigo encontrar o artigo KB, mas se bem me lembro limite .NET 1.x não pode endereço além do 1,5 GB (1,8 GB?) Independentemente de suas configurações.

http://blogs.msdn.com/tmarq/archive/2007/06/25/some-history-on-the-asp-net-cache-memory-limits.aspx http: //social.msdn .microsoft.com / Fóruns / en-US / clr / thread / c50ea343-b41b-467d-a457-c5a735e4dfff http://www.guidanceshare.com/wiki/ASP.NET_1.1_Performance_Guidelines_ -_Caching # Configure_the_Memory_Limit

Outras dicas

Tendo blocos enormes de memória nunca é uma boa idéia, mesmo em 64 bits. Você obter grandes problemas com a memória contígua e fragmentação.

O problema aqui é encontrar um bloco contíguo. Você poderia tentar ativar o modo de 3 GB (que pode ajudá-lo a encontrar mais alguns bytes), mas eu realmente aconselhar contra ele. As respostas aqui são:

  • usar menos memória
  • usar um sistema de banco de dados / arquivo
  • uso x64

Você também pode querer ler o blogue de Eric Lippert (ele parece ter uma entrada de blog para cada pergunta comum .NET ...)

I foram recentemente fazendo uma extensa profiling torno limites de memória no .NET em um processo de 32 bits. Nós todos são bombardeados pela idéia de que podemos alocar até 2.4GB (2 ^ 31) em um aplicativo .NET, mas infelizmente isso não é verdade :(. O processo de aplicação que tem muito espaço para uso e o sistema operacional faz um ótimo trabalho administrá-lo para nós, no entanto, NET em si parece ter sua própria sobrecarga que responde por aproximadamente 600-800MB para aplicações do mundo real típicos que empurram o limite de memória. isto significa que, logo que você alocar uma matriz de inteiros que leva cerca de 1,4 GB, você deve esperar para ver um OutOfMemoryException ().

Obviamente, em 64 bits, este limite ocorre muito depois (chat de deixar em 5 anos :)), mas o tamanho geral de tudo na memória também cresce (Estou achando de ~ 1,7 a ~ 2 vezes) por causa do aumento do tamanho palavra .

O que eu sei com certeza é que a ideia de memória virtual do sistema operacional definitivamente não lhe dá espaço de atribuição de virtualmente infinitas dentro de um processo. Ele está lá apenas para que o 2.4GB completo é endereçável a todos os (muitos) aplicativos em execução ao mesmo tempo.

Espero que esta visão ajuda um pouco.

Eu originalmente respondeu algo relacionado aqui (eu ainda sou um Newby por isso não sei como eu deveria fazer essas ligações):

é existe um limite de memória para um único processo .NET

Você pode alocar muito mais memória do que o ~ 2 GB através da construção de seu aplicativo para uma arquitetura de 64 bits, o que requer que você crie uma nova configuração de compilação no Visual Studio, e que construção da aplicação só será executada em 64-bit versões do Windows. Em .NET, utilizando o "Qualquer CPU" opção de compilação para o seu aplicativo padrão, eu acho que eu sou apenas capaz de alocar cerca de 1,5 GB de memória do heap (máquina Windows, mesmo em 64-bit), que é porque o aplicativo realmente só funciona no modo de 32 bits quando é construído em modo "Qualquer CPU". Mas através da compilação para a arquitetura x64, você pode alocar muito, muito mais memória da pilha durante a execução de sua aplicação, e vou explicar como criar uma compilação x64 para a sua aplicação abaixo:

Mais uma vez, usando o "Qualquer CPU" opção de compilação normal (padrão) no seu projeto .NET, seu aplicativo sempre será executado no modo de 32 bits, mesmo em um sistema operacional Windows de 64 bits. Portanto, você não será capaz de alocar mais de cerca de 1,5 a 2 GB de memória RAM durante a execução do aplicativo. Para executar o aplicativo .NET no modo 64-bit verdade, você terá que ir para o gerente de configuração de compilação e criar um tipo de compilação para a arquitetura x64, e, em seguida, recompilar seu programa para x64 explicitamente usando esse tipo de compilação. A opção de modo x64 build pode ser criado para a sua solução .NET usando as seguintes etapas:

  1. No Visual Studio "Solution Explorer" painel, clique direito sobre o ícone Solution e escolha a opção "Configuration Manager" no menu pop-up. Isso abrirá a construir "Configuration Manager" janela de diálogo para o arquivo .NET Solution.
  2. À direita, lado superior da compilação "Configuration Manager" de diálogo, clique na seta para baixo e selecione a opção "" opção. Isto irá abrir o diálogo "New Platform Solution".
  3. Na caixa de diálogo "New Platform Solution", para a opção de "Plataforma", escolha "x64" a partir do menu drop-down. Em seguida, clique no botão "OK" e, opção nova x64 construção agora estará disponível na caixa de diálogo Configuration Manager.
  4. Em seguida, na caixa de diálogo "Configuration Manager", selecione "x64" no menu drop-down "Platform Solution Ativo". O clique no botão "Fechar".
  5. No Visual Studio painel "Solution Explorer", clique direito sobre o ícone do CS do projeto e escolha a opção "Propriedades" no menu pop-up (a última opção na parte inferior deste menu). Isso abrirá a janela Propriedades do CS Project.
  6. No lado esquerdo da janela de propriedades do CS Project, clique na guia "Build" para mostrar as propriedades de compilação para seu projeto de código. No topo desta janela, aviso de que a "Plataforma" agora deve dizer "x64" (em oposição ao "Qualquer CPU" opção padrão). Se a "Plataforma" drop-down não mostra "x64", você deve selecioná-lo agora.
  7. Em seguida, basta construir o seu código e na pasta "bin", agora você deve ter uma pasta x64 com a nova versão da sua aplicação dentro dele 64-bit.

Usando uma compilação do seu aplicativo em um 64-bit 64-bit Windows OS permitirá que o seu programa para alocar muito mais do que ~ 2GB de memória, presumivelmente até 2 ^ 64 espaços de endereço (se você tem o espaço RAM e disco disponíveis, que são os fatores limitantes reais como parte do tempo de escrever esta resposta).

Se você ainda está a esgotar-se de memória no seu aplicativo, você pode também aumentar o tamanho do arquivo de paginação de memória do Windows. No Windows, o arquivo de página permite que o sistema operacional para a memória mudança da RAM para o disco, se ele ficar sem espaço de memória RAM. Mas há um custo grande momento na mudança seções de memória RAM de e para o disco, por isso pode ser um verdadeiro sucesso no desempenho de sua aplicação. Independentemente do desempenho, aumentando o tamanho da página, você pode (em teoria) fazem o arquivo de página tão grande como há espaço livre disponível na unidade C: do seu computador com Windows. Nesse caso, o aplicativo seria capaz de alocar, por exemplo, até 4 TBde memória (ou qualquer quantidade de memória que o tamanho do arquivo página está definido para) durante a execução de seu programa. Para alterar as configurações do arquivo de página para a sua máquina Windows, faça o seguinte:

  1. Abra o "Propriedades do Sistema" de diálogo com o botão direito em "Este PC" e escolhendo a opção "Propriedades" no menu pop-up. Isso também pode ser realizado em versões posteriores do Windows (Windows 10, Windows 2012 Server, etc ...), vá para "Iniciar"> "Painel de controle"> "Sistema e Segurança"> "Sistema".
  2. No lado esquerdo da caixa de diálogo "System", clique na opção "Propriedades Avançadas do Sistema". Isto irá mostrar a aba "Avançado" do legado "Propriedades do Sistema" de diálogo para Windows.
  3. No separador "Avançado" da caixa de diálogo "Propriedades do Sistema", clique no botão "Configurações" na caixa "Performance". Isso abrirá a caixa de diálogo "Opções de desempenho".
  4. Na caixa de diálogo "Opções de desempenho", clique na aba "Avançado" para ver a configuração atual tamanho do arquivo de página de memória do Windows.
  5. Para aumentar o tamanho do arquivo de página, clique no botão "Alterar" e de diálogo "Memória Virtual" será aberta.
  6. No diálogo "Memória Virtual", selecione a opção "C:" drive, em seguida, em "Tamanho personalizado", defina os e tamanhos "iniciais" "Máximo". Você pode usar qualquer tamanho até ao montante máximo de espaço livre no drive C:, mas fazer essa alteração vai reservar esse espaço para o arquivo de paginação no disco rígido.
  7. Em seguida, clique em "Ok" em todas as caixas de diálogo para confirmar as novas configurações. Em seguida, reiniciar o computador para garantir que todas as alterações foram concluídos corretamente e que as novas configurações de arquivo de página estão em operação.

De qualquer forma, espero que este ajuda as pessoas a entender por que eles podem executar para esse 1,5-2 GB questão limitação de memória em um aplicativo .NET, mesmo quando rodando em uma máquina Windows de 64 bits. Esta pode ser uma questão muito confuso para as pessoas e espero que o meu senso explicação faz. Por favor, fique à vontade para mensagem me com perguntas sobre esta resposta, se necessário.

Eu acho que a questão aqui é que esta aplicação estará adicionando 10MB com cada ciclo faz, eo laço é: "while (true)", que significa que ele irá adicionar estes 10Mbs até o aplicativo está parado. Então, se fosse a correr para 100 loop-lo teria acrescentado perto de 1GBs de RAM, e eu estou supondo que ele teria feito isso em menos de 30 segundos. Meu ponto é que você está tentando a 10 megabyte é de memória por ciclo, em um loop sem fim

Eu realmente sinto muito se eu não receber o seu ponto, mas:

static void Main(string[] args)
{
    ArrayList list = new ArrayList();
    int i = 0;
    while (true)
    {
        using(byte newBt = new byte[1024 * 1024 * 10])
        {
            list.Add(newBt); // 10 MB
            i += 10;
            Console.WriteLine(i);
        }
    }
}

Você já tentou o método usando? E isso pode ser uma pergunta estúpida, mas por que você criar um loop eterno? O se você tentar a tira de código os símbolos>.> XD.

Fonte: http://msdn.microsoft .com / en-us / library / yh598w02 (v = vs.80) .aspx

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top