Bien, entonces mi Fe de Errata y mis disculpas

En ese caso, el dispose del Dataset se debe llamar, porque uno de los
metodos que ejecuta es el GC.SupreesFinalize ... Y por lo tanto la ejecucion
del dispose nos ahorraria el overhead del que habla Carlos.

Carlos, muy bueno!


-----Mensaje original-----
De: puntonet@mug.org.ar [mailto:[EMAIL PROTECTED] En nombre de Carlos A.
Perez
Enviado el: Jueves, 11 de Octubre de 2007 04:09 p.m.
Para: puntonet@mug.org.ar
Asunto: [puntonet] Preguntas varias

Hola

Quiero agregar algo al tema. Suponiendo que estemos hablando solamente de
escritorio, el costo de eliminar por GC un objeto cuya clase tiene
finalizers es mas lento que eliminar un objeto que no lo tenga, por varios
motivos que conspiran para que esto sea así:

El método finalize() obliga a cambiar sobre la marcha el scheduler o plan de
trabajo del GC, ya que al explicitar un finalizer complica la vida al plan
normal del GC. El finalizador es la última cosa en este mundo que un objeto
ejecuta, nada más existe luego del finalizar, y el mismo no puede ejecutarse
a menos que no exista ningún puntero hacia él, que ningún otro objeto pueda
alcanzarlo. Nosotros no podemos saber cuando el GC dispara el finalizador,
porque la naturaleza del GC de .NET es no-determinístico por diseño (la
navegación de grafos de objetos en memoria es random). Como el finalizador
trae aparejado una posible recolección, y la recolección implica una
compactación de memoria, la recolección es un proceso altamente costoso
(stop-the-world operation) y debe dejársela en la medida de lo posible a la
heurística de la máquina virtual.

El GC va examinando el grafo de objetos siguiendo sus punteros, rama por
rama, bifurcación por bifurcación, como un obseso, hasta que determina que
un objeto ya está fuera de alcance por los demás procesos. Este seguimiento,
para un observador externo, es al azar.

Cuando nosotros especificamos la existencia de un FINALIZE() por código
nuestro, la máquina virtual no puede deshacerse del mismo cuando el objeto
queda fuera de alcance, porque si lo elimina directamente, el objeto no
puede decir su "ultima palabra" que es el propio finalizer. Es decir, un
objeto no puede recolectarse en el mismo ciclo que se invoca su finalización
porque primero debe ejecutar justamente su finalizer. Por ello, un
observador externo vería que el CLR deja dereferenciado el objeto y al mismo
tiempo lo "copia" a una "cola de finalización", y no compacta la memoria
porque no puede liberarlo físicamente, ya que no puede asegurar todavía que
ningún objeto lo puede invocar. En este momento, el objeto finalizado existe
en la cola de finalización, y no en la memoria actual de ejecución. Pero no
se puede reclamar todavía la memoria, porque la máquina virtual no está
segura de si no quedaron punteros corruptos (mantiene una copia en la cola
de finalización para procesar justamente esa finalizacion). En este sentido,
recién en el segundo ciclo (es decir, el ciclo de recolección se hace
considerablemente mas largo) el GC puede (a) eliminar el objeto de la cola
de finalización y (b) compactar la memoria.

Para complicar aun más las cosas, en la arquitectura de la máquina virtual,
el overhead que puede crear un objeto con finalizador es significativo,
porque en propio GC no puede correr dentro de su thread a este método,
debido a que no puede correr riesgos de que este finalizador demore
demasiado (demorando entonces la propia recolección), por lo tanto los
procesos FINALIZE() se corren en otro thread distinto al del GC. Esto
adiciona aún más demoras al ciclo de recolección. El thread de finalización
corre en alta prioridad, por lo tanto el resto de los subprocesos quedan
ralentizados.

La recomendación de todo el mundo es NO usar finalizers en la medida de lo
posible. De lo que sabemos del mecanismo de recolección, deducimos que no es
buena idea lanzar una recolección forzada. En tal caso, de ser necesario,
utilizar si está disponible en la versión que manejemos, la interfaz
IDisposable() que nos soluciona algo este tema.

No se si lo hice mas complicado, espero que ayude en algo

Carlos


> -----Mensaje original-----
> De: puntonet@mug.org.ar [mailto:[EMAIL PROTECTED] En nombre de 
> JATEMLIANSKY, Diego Enviado el: Jueves, 11 de Octubre de 2007 10:43 
> a.m.
> Para: puntonet@mug.org.ar
> Asunto: [puntonet] Preguntas varias
> 
> Gente como andan ?
> Tengo un par de preguntas para hacerles que nos están sacando el sueño 
> y que tal vez con algunos tips que nos puedan dar nos puedan orientar 
> un poco como encararlo.
> 
> La arquitectura que tenemos es de FrontEnd en ASP.NET, BackEnd en 
> Servicios de Windows VB.NET accedidos por Remoting y SQL Server.
> (Todo esto instalado en servidores, no instalamos nada en las PC
> clientes)
> 
> Ahora les paso las preguntas (Todas con respecto a la parte del 
> BackEnd en donde tenemos todas las reglas de negocios y el grueso de 
> la
> codificacion):
> 
> 1- Liberar memoria:
>       En algunos casos nos esta costando entender como hacer para liberar 
> memoria.
>       Por un lado encontramos que nos recomiendan hacer los Dispose de los

> DataSets una vez utilizados y por otro lado también encontramos 
> algunos sites que recomiendan hacer un ds = nothing para liberar la 
> memoria, cual es la opción mas recomendable?
> 
>       Por otro lado, que pasa si un método de nuestro BackEnd hace 
> solamente lo siguiente:
> 
>       Function traer() as dataset
>       Dim ds as new dataset
> 
>       ds = CargarDatasetdesdeSQL
> 
>       return ds
>       end function
> 
>       Como hacemos para liberar la memoria utilizada por este DataSet (que

> en algunos casos trae muchos datos para mostrar en pantalla) si 
> después del return no podemos hacer mas nada.
> 
> 2- Prioridad de procesos:
>       Tenemos varios procesos que son del tipo Batch, o sea, que el
usuario 
> levanta un archivo y lo vamos procesando.
>       Estos procesos pueden llevar al procesador a consumir mas de lo que 
> queremos y afectan al funcionamiento optimo del Server. (Ya que en el 
> Server de BackEnd tenemos varios servicios corriendo y no podemos 
> afectar a los
> otros)
>       Como hacemos para establecer prioridades a estos procesos o decirle 
> que solamente consuman hasta por Ej. un 30% o que tengan menor 
> prioridad ?
>       O para que el Loop que hacemos con los registros del archivo no se 
> lleve todo el procesador.
>       (Estos procesos los tenemos que hacer OnLine, no podemos dejarlos 
> como procesos nocturnos)
> 
> 
> Muchas Gracias.
> 
> 
> 
>  AVISO: El presente mensaje y los archivos adjuntos que incluya pueden 
> contener información confidencial de uso exclusivo del destinatario 
> indicado. Cualquier uso en desacuerdo con su propósito, difusión o 
> publicación, total o parcial, se encuentra prohibida. Si recibió este 
> mensaje por error, rogamos reenviarlo al emisor y destruir las copias 
> impresas o grabadas en su sistema. Las opiniones contenidas, son 
> exclusivas de su autor y no representan necesariamente la opinión de 
> OMINT S.A. de Servicios.
> 
> 
> 
> __________ Información de NOD32, revisión 2586 (20071011) __________
> 
> Este mensaje ha sido analizado con NOD32 antivirus system 
> http://www.nod32.com




Responder a