juego para Android: cómo almacenar elementos del juego para que gc no se dispare

8

Estoy desarrollando un juego para Android y tengo una pregunta sobre cómo almacenar los elementos del juego sin disparar el recolector de basura.

Mi juego necesita una colección donde los elementos del juego se almacenan de acuerdo con las posiciones x, y (todos los elementos del juego tienen x, y, ancho y alto). La colección se llama cada cuadro para recuperar los elementos según cameraX, cameraY, ancho y alto de la cámara (el usuario puede desplazarse por el juego).

Ejemplo:

 function draw() {
   tmp = collection.getElements(tmp,cameraX,cameraY,cameraWidth,cameraHeight);
     for(int i = 0; i < tmp.size(); i++) {
        tmp.get(i).draw();
     } 
  }

Actualmente estoy usando la clase Vector para representar los elementos de la colección, pero el gc sigue disparando cada dos minutos. Hago todas mis asignaciones por adelantado. También he modificado la función getElements para aceptar 1 parámetro más: un vector temporal (asignado por adelantado) que se llena con elementos y luego se devuelve.

¿Cómo debo almacenar los elementos del juego para que el gc no se dispare (prefiero nunca si es posible)?

También agrego elementos a la colección durante el tiempo de ejecución, ¿tengo que asignarlos también por adelantado?

Jernej
fuente

Respuestas:

3

Sí, si asigna algo en tiempo de ejecución, eventualmente activará el GC. En general, se soluciona esto implementando un grupo de objetos ... de esa manera, puede preasignar (o al menos recopilar nuevas instancias para reutilizar) todos los objetos como viñetas y otras entidades para evitar activar el GC.

editar: También es posible que desee utilizar un generador de perfiles de memoria (como el analizador de memoria eclipse ) que puede ayudarlo a descubrir qué rutina está generando objetos en tiempo de ejecución.

Joel Martinez
fuente
así que en lugar de usar una clase Vector, ¿usa MyObject []? Pero luego tengo que preasignar el tamaño del grupo de objetos para poder agregar y quitar objetos dinámicamente ... algo como MyObject [] pool = new MyObject [MAX_OBJECTS]; ¿Es esto lo que quisiste decir?
Jernej
más específicamente, si desea evitar al 100% las nuevas asignaciones de objetos, entonces debe asignar cada instancia contenida en esa matriz. Escribí una clase en C # para el marco XNA que logra un buen equilibrio ... solo crea nuevas instancias cuando el grupo no tiene una instancia existente para dar. El resultado es que los primeros segundos pueden asignar algunos objetos, pero una vez que alcanzamos el número máximo de instancias simultáneas, no se producen nuevas asignaciones. Debería ser relativamente fácil de convertir a Java: codecube.net/2010/01/xna-resource-pool
Joel Martinez
2

También sugiero leer el código fuente de Replica Island , que fue desarrollado por un ingeniero de Android. Tiene una clase de grupo de objetos genéricos que se puede ampliar para grupos de objetos personalizados. También tiene una clase de matriz personalizada (con capacidades de agregar / eliminar / buscar) para evitar tener que usar un iterador al atravesar una matriz de objetos.

También me gustaría mencionar que el DDMS en el SDK de Android en Eclipse puede rastrear las asignaciones de memoria (consulte la pestaña Rastreador de asignación en la imagen).

f20k
fuente