2008-12-30 11 views
21

¿Deberían reutilizarse los objetos Java tan a menudo como puedan reutilizarse? ¿O deberíamos reutilizarlo solo cuando son "pesados", es decir, tienen recursos de SO asociados a él?Reutilización de objetos Java

Todos los artículos antiguos en Internet hablan sobre la reutilización de objetos y la agrupación de objetos tanto como sea posible, pero he leído artículos recientes que dicen que new Object() está altamente optimizado ahora (10 instrucciones) y la reutilización de objetos no es tan importante como solía ser.

¿Cuál es la mejor práctica actual y cómo lo está haciendo usted?

Respuesta

14

Dejo que el recolector de basura haga ese tipo de decisión por mí, la única vez que he golpeado el límite de montón con objetos recién asignados fue después de ejecutar un algoritmo recursivo con errores durante un par de segundos que generó 3 * 27 * 27. .. nuevos objetos tan rápido como podría.

Haga lo que sea mejor para la legibilidad y la encapsulación. A veces, reutilizar objetos puede ser útil, pero en general no debes preocuparte por ello.

13

Si los usa muy intensivamente y la construcción es costosa , usted debe tratar de volver a utilizarlos lo más que pueda.

Si sus objetos son muy pequeños y baratos de crear (como Object) debe crear otros nuevos.

Por ejemplo, las bases de datos de conexiones se agrupan porque el costo de crear uno nuevo es más alto que el de crear .. mmhh entero nuevo por ejemplo.

Así que la respuesta a su pregunta es, reutilización cuando son pesados ​​Y se utilizan a menudo (no vale la pena poner en común a 3 mb objeto que sólo se utiliza dos veces)

Editar:

Además, vale la pena leer este elemento de Effective Java: Favor Immutability y se puede aplicar a su situación.

+0

+1 Otro buen fragmento de Bloch (segunda edición) es el artículo 5, "Evita crear objetos innecesarios".Los últimos párrafos de este artículo tienen algunos buenos consejos e información. –

+0

De ese mismo artículo por Bloch: * "Este artículo no debe interpretarse erróneamente como una creación de objeto costosa y debe evitarse. Por el contrario, la creación y recuperación de pequeños objetos cuyos constructores hacen poco trabajo explícito es barata ... "* –

3

La regla de oro debe ser el uso de su sentido común y la reutilización de los objetos cuando su creación consume recursos significativos tales como E/S, el tráfico de red, las conexiones de base de datos, etc ...

si es sólo la creación de una nueva String(), olvídate de la reutilización, no obtendrás nada de ella. La legibilidad del código tiene una preferencia más alta.

3

Me preocuparía por problemas de rendimiento si surgen. Haz lo que tenga sentido primero (¿harías esto con primativos?), Si luego ejecutas una herramienta de creación de perfiles y descubres que es algo nuevo que te causa problemas, comienza a pensar en la preasignación (es decir, cuando tu programa no está haciendo mucho trabajo)

objetos reutilizando suena como un desastre a punto de ocurrir por cierto:

SomeClass someObject = new SomeClass(); 

someObject.doSomething(); 
someObject.changeState(); 
someObject.changeOtherState(); 
someObject.sendSignal(); 
// stuff 

//re-use 
someObject.reset(); // urgh, had to put this in to support reuse 
someObject.doSomethingElse(); // oh oh, this is wrong after calling changeOtherState, regardless of reset 
someObject.changeState(); // crap, now this is wrong but it's not obvious yet 
someObject.doImportantStuff(); // what's going on? 
+0

Por supuesto. Si vuelve a usar, tiene que diseñar para la reutilización de objetos, y no dejar que la suerte. Las conexiones a la base de datos se reutilizan y tienen un método "cerrado" para limpiar los recursos (originalmente también eliminan la conexión) pero las DatabasePools envuelven esas conexiones para permitir que se realice la limpieza pero ... – OscarRyz

+0

... dejan abierta la conexión. Por supuesto, sería un desastre, por ejemplo, volver a insertar un objeto previamente insertado. O bien, realice una transacción iniciada previamente utilizada en otro lugar del código. Debe considerar y diseñar para su reutilización muy pocas veces. – OscarRyz

+0

Claro, pero estas son cosas que se prestan para reutilizar. La operación estaba hablando de objetos grandes (cuyo estado sería presumiblemente complejo) en lugar de recursos reales. – billybob

1

creación de objetos es sin duda más rápido de lo que solía ser. El GC generacional más nuevo en los JDK 5 y superiores también son mejoras.

No creo que ninguno de estos haga que la creación excesiva de objetos sea gratuita, pero sí reducen la importancia de la agrupación de objetos. Creo que la agrupación tiene sentido para las conexiones de bases de datos, pero no lo intento para mis propios objetos de dominio.

Reutiliza la seguridad de subprocesos. Debe pensar detenidamente para asegurarse de poder reutilizar los objetos de forma segura.

Si decidí que la reutilización de objetos era importante, lo haría con productos como Terracotta, Tangersol, GridGain, etc. y me aseguraría de que mi servidor tuviera memoria disponible.

8

Deje que el recolector de basura haga su trabajo, se puede considerar mejor que su código.

A menos que un generador de perfiles lo pruebe culpable. Y ni siquiera uses el sentido común para tratar de descubrir cuándo está mal. En casos inusuales incluso los objetos baratos como los arrays de bytes se combinan mejor.

  • Regla 1 de optimización: no lo hagas.
  • Regla 2 (solo para expertos): no lo hagas todavía.
1

En segundo lugar los comentarios anteriores.

No intente adivinar el GC y el Hotspot. La agrupación de objetos puede haber sido útil una vez, pero actualmente no es tan útil a menos que esté hablando de conexiones de bases de datos o recursos únicos del sistema.

Simplemente intente y escriba código limpio y simple y se sorprenderá de lo que puede hacer Hotspot.

¿Por qué no utilizar VisualVM o un generador de perfiles para echar un vistazo a su código?

7

La creación de objetos es barata, sí, pero a veces no lo suficientemente barata.

Si crea mucho (y me refiero a MUCHO) objetos temporales en rápida sucesión, los costos para el recolector de basura son considerables. Sin embargo, incluso con un buen generador de perfiles, es posible que no vea los costos fácilmente, ya que el recolector de basura hoy en día trabaja en intervalos cortos en lugar de bloquear toda la aplicación por un segundo o dos.

La mayoría de las mejoras de rendimiento que obtuve en mis proyectos provinieron tanto de evitar la creación de objetos como de evitar todo el trabajo (incluida la creación de objetos) a través de un almacenamiento en caché agresivo. No importa cuán grande o pequeño sea el objeto, aún lleva tiempo crearlo y administrar las referencias y las estructuras de pila para él. (Y, por supuesto, la limpieza y el montón-desfragmentación/copia interna también lleva tiempo.)

no partiría ser religioso acerca de evitar la creación de objetos en todo costo, pero si usted ve un patrón de rompecabezas en su memory-profiler, significa que su recolector de basura está en servicio pesado. Y si su recolector de basura usa la CPU, el CPI no está disponible para su aplicación.

En cuanto a la agrupación de objetos: Hacer las cosas bien y no tener fugas de memoria o estados no válidos o pasar más tiempo en la administración de lo que ahorraría es difícil. Entonces nunca usé esa estrategia.

Mi estrategia ha sido simplemente luchar por los objetos inmutables. Las cosas inmutables se pueden almacenar en caché fácilmente y, por lo tanto, ayudan a mantener el sistema simple.

Sin embargo, no importa lo que hagas: asegúrate de verificar primero tus puntos de acceso con un generador de perfiles. La optimización prematura es la raíz de la mayoría de la maldad.