Pergunta

Estou um pouco confuso sobre o fato de que em C# apenas os tipos de referência são coletados como lixo.Isso significa que o GC escolhe apenas os tipos de referência para desalocação de memória.Então, o que acontece com os tipos de valor, pois eles também ocupam memória na pilha?

Foi útil?

Solução

Para começar, estejam na pilha ou parte da pilha depende do contexto de que parte - se estiverem dentro de um tipo de referência, eles estarão na pilha de qualquer maneira. (Você deve considerar o quanto você realmente se importa com a divisão de pilha/heap de qualquer maneira - como Eric Lippert escreveu, é em grande parte um detalhe de implementação.)

No entanto, basicamente a memória do tipo de valor é recuperada quando o contexto é recuperado - portanto, quando a pilha é lançada por você retornando de um método, que "recupera" todo o quadro da pilha. Da mesma forma, se o valor do tipo de valor fizer parte de um objeto, a memória será recuperada quando esse objeto é coletado de lixo.

A resposta curta é que você não precisa se preocupar com isso :) (isso pressupõe que você não tem nada outro do que a memória para se preocupar, é claro - se você tem estruturas com referências a alças nativas que precisam ser lançadas, esse é um cenário um pouco diferente.)

Outras dicas

Estou um pouco confuso com o fato de que, em C#, apenas os tipos de referência recebem lixo coletado.

Isso não é um fato. Ou melhor, a verdade ou a falsidade dessa afirmação depende do que você quer dizer com "Obtenha o lixo coletado". O coletor de lixo certamente analisa os tipos de valor ao coletar; Esses tipos de valor podem estar vivos e segurando um tipo de referência:

struct S { public string str; }
...
S s = default(S); // local variable of value type
s.str = M(); 

Quando o coletor de lixo corre, certamente olha para S, porque precisa determinar que o S.STR ainda está vivo.

Minha sugestão: esclarecer precisamente O que você quer dizer com o verbo "recebe o lixo coletado".

O GC escolhe apenas os tipos de referência para des-alocação de memória.

Novamente, isso não é um fato. Suponha que você tenha uma instância de

class C { int x; }

A memória para o número inteiro estará na pilha coletada de lixo e, portanto, recuperada pelo coletor de lixo quando a instância de C se tornar sem raiva.

Por que você acredita na falsidade que apenas a memória dos tipos de referência é desalocudada pelo coletor de lixo? A afirmação correta é aquela memória que era alocado pelo coletor de lixo é desalocado pelo coletor de lixo, que eu acho que faz todo o sentido. O GC o alocou para que seja responsável por limpá -lo.

Então, o que acontece com os tipos de valor, pois eles também ocupam memória na pilha?

Nada acontece com eles. Nada precisa acontecer com eles. A pilha é um milhão de bytes. O tamanho da pilha é determinado quando o encadeamento é iniciado; Começa em um milhão de bytes e permanece um milhão de bytes durante toda a execução do fio. A memória na pilha não é criada nem destruída; Somente seu conteúdo é alterado.

Existem muitos verbos usados ​​nesta questão, como destruído, recuperado, desalocado, removido.Isso não corresponde bem ao que realmente acontece.Uma variável local simplesmente deixa de ser, Estilo papagaio norueguês.

Um método possui um único ponto de entrada, a primeira coisa que acontece é que o ponteiro da pilha da CPU é ajustado.Criando um “stack frame”, espaço de armazenamento para as variáveis ​​locais.O CLR garante que esse espaço seja inicializado com 0, caso contrário, não é um recurso que você usa fortemente em C# por causa da regra de atribuição definida.

Um método tem um único ponto de saída, mesmo se o código do seu método estiver repleto de vários return declarações.Nesse ponto, o ponteiro da pilha é simplesmente restaurado ao seu valor original.Na verdade, ele "esquece" que as variáveis ​​locais estão sempre presentes.Seus valores não são 'eliminados' de forma alguma, os bytes ainda estão lá.Mas eles não durarão muito, a próxima chamada do seu programa irá sobrescrevê-los novamente.A regra de inicialização zero do CLR garante que você nunca poderá observar esses valores antigos, o que seria inseguro.

Muito, muito rápido, não leva mais do que um único ciclo de processador.Um efeito colateral visível desse comportamento na linguagem C# é que os tipos de valor não podem ter um finalizador.Garantindo que nenhum trabalho extra precise ser feito.

Um tipo de valor na pilha é removido da pilha quando fica fora do escopo.

Em primeiro lugar, deixe-me dizer que isso é muito viável, mas não será sem uma quantidade significativa de esforço tanto em pensar no design certo e na implementação. Não há solução rápida aqui, tendo dito que aqui estão suas opções.

O que você basicamente precisa olhar é reivindicações aumentadas, isto é, você precisa de uma maneira de aumentar o conjunto de reivindicações que o SharePoint está ciente de seus usuários autenticados. O SharePoint permite proteger itens contra reivindicações.

Você pode fazer um aumento de reivindicações de várias maneiras, mas os dois mais comuns são:

adfs - você já sugeriu isso, mas se o ADFS for usado como um provedor de identidade personalizado para o seu aplicativo, poderá usar regras de reivindicação do ADFS e armazenamentos de atributos para consultar o banco de dados SQL e atribuir novas reivindicações para o seu usuário. Você só precisa garantir o SharePoint usando essas novas reivindicações. Se você está seguindo esta rota, basicamente leia tudo o que Steve Peschka já publicou sobre o assunto, começando com isso:

http://blogs.technet.com/b/speschka/archive/2010/07/30/configuring-sharepoint-2010-and-adfs-v2-end-to-end.aspx

Para encontrar mais informações sobre como usar um armazenamento de atributo SQL em ADFS para reivindicações de AUFS, dê uma olhada nesta:

http://blogs.technet.com/b/vinitt/arkive/2013/04/15/How-To-Po-Po-Custom-sql- Attribute-store-to-gerate-reivindicações-e-autorize-user.aspx

provedor de reivindicação personalizado - você pode escrever um provedor de reivindicação personalizado para o SharePoint e registrá-lo em seu aplicativo da Web, você precisará gravar todo o código para consultar o banco de dados e processar os valores retornados, mas Estou supondo que não seja um problema. Esta opção realmente oferece mais controle sobre a experiência do usuário em proteger o SharePoint como ADFs por conta própria não permitirá que você integre qualquer validação ou aspectos de pesquisa no seletor de reivindicação (selecionador de pessoas). De fato, que aparecerá que qualquer valor pesquisado no selecionador das pessoas é válido se ele existe como um valor de atributo válido ou não, isso é muito aberto ao erro humano ao proteger itens no SharePoint, para que você possa considerar um híbrido Abordagem que usa o ADFS para o aumento das reivindicações, mas também tem um provedor de reivindicação personalizado para permitir a pesquisa e resolva nomes do banco de dados SQL.

Mais informações e um ponto de partida para provedores de reclamação personalizados podem ser encontrados aqui:

http://msdn.microsoft. com / pt-us / biblioteca / gg615945% 28V= escritório.14% 29.aspx

Embora novamente Steve Peschka escrevi muitas postagens de blog sobre este assunto e eu recomendo dar uma olhada em todos eles como você constrói um design.

Este é apenas um pontapé inicial na direção certa e sem dúvida você terá mais perguntas antes de obter todas as respostas que você precisa.

Espero que ajude.

Os tipos de valor seriam desalocados quando o quadro da pilha for removido depois de ser executado, eu assumiria

Também gostaria de adicionar que a pilha está no nível do encadeamento e o Heap está no nível do domínio do aplicativo.

Portanto, quando um encadeamento termina, ele recuperaria a memória da pilha usada por esse encadeamento específico.

Cada instância do tipo de valor no .NET fará parte de outra coisa, que pode ser uma instância de tipo de valor em anexo maior, um objeto de heap ou um quadro de pilha. Sempre que alguma dessas coisas surgir, quaisquer estruturas dentro delas também surgirão; Essas estruturas continuarão a existir enquanto a coisa que as contém. Quando a coisa que contém a estrutura deixar de existir, a estrutura também será. Não há como destruir uma estrutura sem destruir o recipiente, e não há como destruir algo que contém uma ou mais estruturas sem destruir as estruturas nela contidas.

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