2009-02-24 7 views
20

Lo siento si esta es una pregunta obvia, pero ni Google ni una búsqueda aquí me llevaron a una respuesta.¿Cómo eliminar una matriz en C#?

¿Hay alguna manera de eliminar una matriz por completo?

Quiero el contrario de int[] array = new int[5]

+1

@ShuggyCoUk Bueno, en realidad estoy haciendo un curso universitario y llenando los espacios en blanco (desafortunados) que nos deja nuestro profesor que no están cubiertos por la literatura con preguntas. Creo que el arte de hacer preguntas es más importante para aprender que las respuestas, así que sigo preguntando cuando no puedo encontrar una respuesta –

+0

posible duplicado de [¿Cuánta memoria libre usa una lista grande en C#?] (Http: // stackoverflow.com/questions/17955346/how-free-memory-used-by-a-large-list-in-c) – bigge

+1

@bigge Y cómo exactamente es la pregunta de 2009 con más votos positivos y respuestas de un duplicado de la publicada este julio? –

Respuesta

33

Diga usted llama:

void Foo(){ 
    int[] a = new int[5]; 
} 

En C# no hay manera de quitar la definición de la variable a. Eso significa que a se definirá en Foo incluso si establece a como nulo. Sin embargo, al final de Fooa quedará fuera del alcance. Eso significa que ningún código puede hacer referencia a él, y el recolector de basura se encargará de liberar la memoria la próxima vez que se ejecute, lo que podría no ser por mucho tiempo.

+3

Tengo que amar las respuestas definitivas :) Muchas gracias por salvarme de buscar en Google por mucho más tiempo. –

+0

Sé que este es un hilo antiguo, pero espero que alguien pueda ayudar. He observado el GC administrado, el código de red realmente no hace un buen trabajo hasta que se cierra la aplicación. Cuando la asignación y eliminación de memoria para arrays u objetos ocurre con mucha frecuencia y repetición, la memoria no se libera incluso cuando los bloques de uso() {} están en su lugar. He observado que sigue sumando en el Administrador de tareas mientras estoy sentado en el borde de mi silla preguntándome cómo controlarlo antes de que se cuelgue. ¿Hay algún secreto indocumentado aquí? –

+0

@Pradeep Puranik, creo que tendrás más suerte haciendo una nueva pregunta. – RossFabricant

16

Sólo tienes que dejarlo ir fuera de alcance, y esperar a GC para encontrarlo; que podría no ser inmediato (de hecho, casi con certeza no lo será). Si tiene un campo en un objeto de larga duración (que permanecerá dentro del alcance), puede establecerlo en nulo, lo cual puede ayudar.

Puede influir en el GC para recopilar antes (no solo su objeto: todo lo que reúne los requisitos), pero rara vez si alguna vez lo hace. Lo uso solo en plataformas de prueba; pero:

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); // DON'T DO THIS!!! 

para más información sobre GC.Collect:

+3

+1 para contar GC. –

5

No hay necesidad de eliminar la matriz, la GC se ocupará de ella.

(Muy) De manera simplista:

Cuando se agota la memoria del recolector de basura entrará en funcionamiento, deje su código y recorrer todos los objetos vivos en la memoria.
en vivo significa alguna referencia en la pila, un registro, una referencia estática y algunas otras cosas conocidas colectivamente como 'GC Roots'. Al atravesarlos, nota que están vivos.

Si su matriz ya no está activa, ya no hay forma de que algo pueda acceder a ella (eso es lo que determina la vida), de modo que la memoria que ocupa estará disponible para su reutilización.

Hay puede ser una razón para asignar la referencia a null si se sostendría referencias vivo más tiempo de lo que se desea o se está llevando a cabo una gran cantidad de memoria que necesita de inmediato, pero esto puede ser contraproducente y hacer que la matriz realidad vivir más tiempo. Instalar en lugar de variables de pila son mejores candidatos para esta optimización si la instancia contiene una vida considerablemente más larga que la matriz que contiene.

Para ser claros, como un principiante no debe considerar este tipo de cosas, que el GC hacer su trabajo y sólo tratan de evitarlo cuando:

  1. sabe que necesita a
  2. saben cómo
  3. saber cómo comprobar lo hiciste bien
3

array = null, pero creo que va a ser una buena idea si usted lee un poco sobre el modelo de gestión de memoria .NET para entender completamente por qué.

+0

¿Realmente merezco un voto negativo por esto? – Trap

+1

He votado porque no creo que merecieras el voto negativo :) – Gautam

+0

¡Bien, gracias! : D – Trap

1

Lo más parecido que se obtiene es esperar a que se salga del alcance o establecerlo como nulo.

No va a quitar o eliminar la matriz de inmediato, pero después se le cae todas las referencias a la matriz, el recolector de basura (GC) se eliminará en el tiempo ...

3

Solo para aclarar en caso de que don No entiendo parte de la terminología expresada en las otras respuestas, GC significa recolector de basura. Los lenguajes como C# que tienen administración de memoria automática le permiten concentrarse en hacer lo que necesita hacerse y no preocuparse por lo que está creando y cuándo eliminarlo. El GC funciona revisando periódicamente todos los objetos que crea y viendo si tienen alguna referencia a ellos. De lo contrario, esto significa que no hay forma de que pueda hacer algo con ellos, por lo que también podrían eliminarlos, y el sistema hace precisamente eso.

Para más detalles, ver http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)

+0

Exactamente. C# no es C++. –

4

Debe leer Chris Brumme's article on the subject; los primeros párrafos deberían explicar la situación.

Y cualquiera que sugiere "asignar nula a la variable" debe tomar nota en particular de la parte que dice:

Incluso si se agrega “AC = null;” después de su uso de ella, el JIT es gratis considerar esta tarea como un código muerto y eliminarla.

-4

Esto puede haber sido resuelto, pero podría tratar la matriz como una pila. Haz un bucle y destapa la parte superior de cada iteración.

while(true) 
{ 
    if(array.Length==0) 
    { 
     break; 
    } 
    array.Pop(); 
} 

esta manera sólo se puede empujar más valores en la matriz sin tener que volver a crear una instancia que

+0

explicar el voto a favor? la reinstalación de una matriz cada vez que desea restablecer los valores parece una pérdida de memoria – DWolf

-2

en C++ no es la palabra clave delete eliminar cualquier cosa que desee de la memoria. Por supuesto, también puede eliminar matrices, de modo que puede escribir una función en C++ que toma una matriz como parámetro, y en la implementación solo agrega una línea de código que lo borra inmediatamente. Si esta función pertenece a una clase en un proyecto de biblioteca de clase, entonces puede agregar la referencia en C#, crear la instancia usando el espacio de nombres y llamar a la función, o no crear la instancia, si la función fue declarada estática.

Si el tipo de proyecto en C++ no era una biblioteca de clases, sino solo un archivo dll, debe exportar la función declarada (extern "C" __declspec (dllexport) y en C# usarlo usando System.Runtime.InteropServices.DllImport. Cuando use dll import , es importante que especifique la cadena de ruta del archivo dll y después de agregar la llamada Convention = CallingConvention. Cdecl, si no desea obtener excepciones y problemas cada vez que llame a la función importada.

Puede leer en Internet cómo hacer todo esto. Espero que esta sea una buena idea.

Código ejemplo:

proyecto DLL

C++:

extern "C" __declspec(dllexport) void Delete(array<__int32>^ arr) 
{ 
    delete arr; 
} 

C#:

using System; 
using System.Runtime.InteropServices; 
namespace DeleteArray 
{ 
    class Program 
    { 
     [DllImport("...DeleteArray.dll", Convention=CallingConvention)] 
     static extern void Delete(int[] arr); 

     static int Main(string[] args) 
     { 
      int[] array = new int[] { 1, 2, 3, 4, 5 }; 
      foreach (int integer in array) 
      { 
       Console.WriteLine(integer); 
      } 
      Delete(array); 
      Console.Write(array[0]); //Runtime error! 
      return 0; 
     } 
    } 

}

He intentado esto en casa y ha funcionado excelente para mí, entonces ¿por qué no a otros también?

+0

¿Cómo es esta una respuesta? –

0

Puede declarar e inicializar su matriz en una instrucción if (true) {}, fuera de la instrucción if (después de ella) la variable de matriz no es accesible, por lo que se eliminará.

0

En C++ se puede utilizar la palabra clave delete. Y fue mencionado originalmente en este comentario y en otros comentarios. El historial de edición muestra esto. Esta es una respuesta viable (aunque lateral) incluso si otros no entienden por qué. Digo esto porque uno puede usarlo para encontrar su propia solución elegante, si entienden más de un idioma.

En .NET/MSIL, tiene la palabra clave eliminar, pero se llama nombre de variable. Deshacer(). Estoy ofreciendo esto porque elimina todas las referencias a la variable y la coloca en un estado de preparación para la recolección de basura. Otra opción es establecer la variable igual a nulo, ya que mantendrá la variable como un objeto tipeado, pero liberará lo que tenía en la recolección de elementos no utilizados, para que pueda ser reasignada más tarde.

original Comentario/respuesta:

La recolección de basura para C# es grande y todo, pero a veces se necesita realmente para eliminar una variable de la memoria y hacer una nueva instancia de la misma, sin alguna otra parte de su mantenimiento programa esta vivo Uno tiene la capacidad de colocar potencialmente el trozo existente de la memoria en poder de la matriz en un estado GC, señalando la matriz en una nueva pieza de memoria, tales como:

aMyArray = new int[]; 

El principal problema que puedo ver con de esta manera, sin embargo, es que realmente no quiere perder una tonelada de memoria, y luego todo se detiene bruscamente cuando se inicia GC porque el sistema operativo está volviendo loco. Sostengo este pensamiento, considerando que C Sharp ahora es un lenguaje convencional y se usa en MUCHAS aplicaciones diferentes, incluyendo juegos de escritura ... Sería realmente agradable si C Sharp no actuó de forma similar a ActionScript/FLASH en este el respeto.

Cuestiones relacionadas