Pergunta

O nosso serviço tende a cair no sono durante as noites no servidor do nosso cliente, e depois ter um tempo duro acordar. O que parece acontecer é que a pilha do processo, que é, por vezes, várias centenas de MB, é movido para o arquivo de swap. Isso acontece à noite, quando o nosso serviço não é usado, e outros estão programados para executar backups (DB, AV scans etc). Quando isso acontece, depois de algumas horas de inatividade a primeira chamada para o serviço leva até alguns minutos (consequentes chamadas demorar alguns segundos).

Estou bastante certo de que é um problema de gerenciamento de memória virtual, e eu realmente odeio a idéia de forçar o OS para manter o nosso serviço na memória física. Eu sei que fazendo isso irá prejudicar outros processos no servidor, e diminuir o rendimento global do servidor. Tendo dito isto, nossos clientes querem apenas nosso aplicativo para ser responsivo. Eles não se importam se os trabalhos noturnos demorar mais tempo.

Eu me lembro vagamente que há uma maneira de forçar o Windows para manter páginas na memória física, mas eu realmente odeio essa idéia. Eu estou mais inclinado para alguns watchdog interno ou externo que iniciará funcionalidades de nível superior (já há algum programador interna que faz muito pouco, e não faz diferença). Se houvesse uma ferramenta terceira parte que forneceu esse tipo de serviço é teria sido tão bom.

Eu adoraria ouvir quaisquer comentários, recomendações e soluções comuns para este tipo de problema. O serviço é escrito em VC2005 e é executado em servidores Windows.

Foi útil?

Solução

Como você mencionou, forçando o aplicativo para estadia em memória não é a melhor maneira de compartilhar recursos na máquina. Uma solução rápida que você pode achar que funciona bem é simplesmente programar um evento que desperta o seu serviço em um momento específico a cada manhã antes que seus clientes começam a usá-lo. Você pode apenas agendar com o agendador de tarefas do Windows com um script simples ou chamada de EXE.

Outras dicas

Eu não estou dizendo que você quer fazer isso, ou que é melhor prática, mas você pode achar que funciona bem o suficiente para você. Parece para corresponder ao que você pediu.

Resumo:. Toque cada página no processo, na página de cada vez, em uma base regular

Que tal uma linha que corre no fundo e acorda uma vez a cada N segundos. Cada vez que a página acorda, ele tenta ler a partir de X. endereço A tentativa é protegido com um manipulador de exceção no caso de você ler um endereço incorreto. X, em seguida, incremento do tamanho de uma página.

Existem 65536 páginas de 4GB, 49152 páginas de 3GB, 32768 páginas de 2GB. Divide o seu tempo ocioso (tempo durante a noite morto) por quantas vezes você quiser (tentativa) para acertar cada página.

BYTE *ptr;

ptr = NULL;
while(TRUE)
{
    __try
    {
        BYTE b;

        b = *ptr;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        // ignore, some pages won't be accessible
    }

    ptr += sizeofVMPage;

    Sleep(N * 1000);
}

Você pode obter o valor sizeOfVMPage do valor dwPageSize no resultado retornado de GetSystemInfo ().

Não tente evitar o manipulador de exceção usando if (! IsBadReadPtr (PTR)), porque outros segmentos no aplicativo pode ser modificando proteções de memória ao mesmo tempo. Se você conseguir descolar devido a esta é quase impossível identificar por que (ele provavelmente será uma condição de corrida não-repetível), então não perca tempo com ele.

Claro, você iria querer transformar esta discussão durante o dia e só executá-lo durante o seu tempo morto.

Uma terceira abordagem poderia ser a de ter o seu serviço funcionar uma linha que faz algo trivial como incrementar um contador e, em seguida, dorme por um período bastante longo, digamos, 10 segundos. Thios deve ter um efeito mínimo sobre outras aplicações, mas manter pelo menos algumas de suas páginas disponíveis.

A outra coisa a garantir é que os seus dados estão localizados.

Em outras palavras: você realmente precisa de todos os 300 MiB de memória antes de poder fazer alguma coisa? Podem as estruturas de dados que você usa ser reorganizados de modo que qualquer pedido específico poderiam ser satisfeitas com apenas alguns megabytes?

Por exemplo

  • Se o seu 300 MiB de memória heap contém dados de reconhecimento facial. Podem os dados internamente ser organizadas de modo que os dados das faces masculinas e femininas são armazenados juntos? Ou big-nãos são separados a partir de pequenos-narizes?

  • se ele tem algum tipo de estrutura lógica para isso pode ser que ordenado? de modo que uma busca binária pode ser usada para pular um monte de páginas?

  • se é um propritary, in-memory, o motor de banco de dados, podem os dados ser melhor indexado / agrupado para não exigir tantos acessos à página de memória?

  • Se eles estão texturas texturas de imagem, pode comumente utilizados ser localizados próximos uns dos outros?

Você realmente precisa de todos os 300 MiB de memória antes de poder fazer alguma coisa? Você não pode solicitação de serviço sem todas os dados de volta na memória?


Caso contrário:. tarefa agendada em 6 ?? para despertá-lo

Em termos de custo, a solução mais barata e mais fácil é provavelmente apenas para comprar mais memória RAM para esse servidor, e então você pode desativar completamente o arquivo da página. Se você estiver executando 32-bit do Windows, basta comprar 4GB de RAM. Em seguida, todo o espaço de endereço será feito com memória física, e o arquivo de página não estará fazendo nada mesmo.

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