¿5% del tiempo de ejecución empleado en GC? 10%? 25%?.NET: ¿Cuál es la sobrecarga del recolector de basura típico?
Gracias.
¿5% del tiempo de ejecución empleado en GC? 10%? 25%?.NET: ¿Cuál es la sobrecarga del recolector de basura típico?
Gracias.
Como han dicho otros, depende. Pero, sólo para su lectura:
Además, mi pregunta sería - ¿por qué estás preocupado por la sobrecarga (o si son sólo curiosidad de un punto de vista académico)? Si hay una situación específica en la que cree que el recolector de basura afectará el rendimiento de su aplicación, pregunte sobre esa situación y podrá obtener mejores respuestas. De lo contrario, hay cosas más importantes de las que preocuparse (desde el punto de vista del rendimiento) que el recolector de basura, el primero es tu propio código/algoritmo/etc.
¡Gracias, ambos artículos son geniales! Es sobre todo un interés académico, en algunos artículos se mencionó un 20% de gastos generales en un par de puntos de referencia, y fue realmente sorprendente para mí. Así que solo quiero encontrar lo que otros piensan sobre las pérdidas de rendimiento del GC. –
¡Qué buena publicación de blog es la primera! :) –
@Earwicker - Jaja ... conseguí un +1 por eso. ;-) (Y fue una lectura interesante, ¡así que gracias!) – JasCav
Depende completamente de la aplicación. La recolección de basura se realiza según sea necesario, por lo que cuanto más frecuentemente asigne grandes cantidades de memoria que más tarde se convierte en basura, más a menudo se debe ejecutar.
Incluso podría ir tan bajo como 0% si asigna todo por adelantado y nunca asigna ningún objeto nuevo.
En las aplicaciones típicas, creo que la respuesta es muy cercana al 0% del tiempo que se gasta en el recolector de basura.
Entiendo que depende mucho del uso de la memoria, pero ¿hay algunas expectativas generales típicas? –
@vladimir una expectativa típica es no tener que preocuparse en absoluto – sfussenegger
This blog post tiene una investigación interesante en esta área.
¿La conclusión de los carteles? Que los gastos generales fueron insignificantes para su ejemplo.
Así que el montón GC es tan rápido que en un programa real, incluso en los bucles, puede utilizar los cierres y los delegados, sin siquiera darle el pensamiento de un segundo (o incluso el pensamiento de unos pocos nanosegundos). Como siempre, trabaje en un diseño limpio y seguro, luego haga un perfil para descubrir dónde está la sobrecarga.
Su conclusión es muy clara. Su punto final para la correcta limpieza, código seguro y luego perfil para encontrar problemas es probablemente el mejor consejo.Para conocer su sobrecarga real, realice algunas pruebas y algunos perfiles de memoria. Entonces lo sabrás con certeza. –
Creo que esta publicación de blog es un poco engañosa. El autor está ejecutando una prueba de un solo subproceso y usa diferencias simples de inicio y fin para "medir" la sobrecarga del GC. En realidad, está midiendo sobrecarga para lambda mientras que GC funcionará en un hilo diferente. (Al menos eso es lo que esperaría que hiciera. ¿Alguien podría confirmar o refutar esto?) – sfussenegger
@sfussenegger, por lo que puedo recordar, ejecuté la prueba en una máquina virtual que estaba configurada para usar un solo núcleo físico máquina. En cualquier caso, si funciona mejor en múltiples núcleos, ese es otro argumento a favor de GC sobre la administración manual de la memoria. –
Mire el video de Red Gate here. La mejor explicación de GC que he encontrado.
La sobrecarga varía ampliamente. En realidad no es práctico para reducir el dominio del problema en "escenarios típicos" debido a la sobrecarga de GC (y las funciones relacionadas, como la finalización) dependen de varios factores:
Se puede analizar el impacto de varios puntos en cada uno de esos ejes de relevancia (y probablemente haya áreas más relevantes que no me vuelvo loco), así que el problema es realmente "cómo ¿Puedes reducir esos ejes de relevancia a un 'escenario común'? "
Básicamente, como dijeron otros, depende. O bien, "lo suficientemente bajo como para que no deba preocuparse hasta que aparezca en un informe de perfilador".
Sí, el recolector de basura pasará un X% de tiempo recopilando cuando se promedia sobre todas las aplicaciones en todas partes. Pero eso no necesariamente significa que el tiempo está sobrecargado. En el caso de los gastos generales, realmente solo se puede contar el tiempo que queda después de liberar una cantidad equivalente de memoria en una plataforma no administrada.
Con esto en mente, la sobrecarga real es negativo , pero el recolector de basura ahorrar tiempo ser liberar varios fragmentos de memoria en lotes. Eso significa menos interruptores de contexto y una mejora general en la eficiencia.
Además, a partir de .Net 4 el recolector de basura hace mucho trabajo en un hilo diferente que no interrumpe tanto el código actualmente en ejecución. A medida que trabajamos más y más con máquinas mutli-core donde un núcleo puede incluso estar inactivo de vez en cuando, esto es un gran problema.
Realmente puede variar. Mira este programa de demostración short-but-complete que escribí:
http://nomorehacks.wordpress.com/2008/11/27/forcing-the-garbage-collector/
que muestra el efecto de grandes colecciones de basura Gen2.
En C/C++ nativo a veces existe un costo de asignación de memoria debido a la búsqueda de un bloque de memoria libre del tamaño correcto, también hay un costo de 0 para liberar la memoria debido a tener que vincular la memoria liberada en la lista correcta de bloques y combina bloques pequeños en bloques grandes.
En .NET es muy rápido asignar un nuevo objeto, pero usted paga el costo cuando se ejecuta el recolector de elementos no utilizados. Sin embargo, al costo de recolección de basura objeto de vida corta es lo más cercano a la libertad que pueda obtener.
Siempre he encontrado que si el costo de recolección de basura es un problema para usted, entonces es probable que tenga problemas más grandes con el diseño de su software. La megafonía puede ser un gran problema con cualquier GC si no tiene suficiente memoria RAM física, por lo que quizás no pueda simplemente poner todos sus datos en la RAM y depender del sistema operativo para proporcionar memoria virtual según sea necesario.
No sé .NET, pero estoy seguro de que sé la respuesta: ¡depende! :) – sfussenegger
Si le preocupa el rendimiento de .NET, entonces el recolector de basura no debería ser su principal preocupación. Si escribe código algorítmico (procesamiento de señal, compresión), puede esperar una desaceleración significativa al transferir algoritmos de C++ a .NET. En los ejemplos que he visto, es más de dos veces más lento. Si no lo hace, todas las sobrecargas de .net son insignificantes en comparación con el tiempo que espera el acceso al disco o las bibliotecas no administradas. –