Resultado de etiquetas “memory”

Estoy de reenganche con mis proyectos tras venirme de vacaciones (la primera vez que descanso un mes entero, se hace duro). Además, me he actualizado la versión de OSX a Snow Leopard ...

Oh, sorpresa, las pruebas de uno de los proyectos fallan con un místico Invalid memory access for location.

Mi conclusión, después de buscar mucho en google, es que se trata de algún tipo de bug en la gestión de memoria que ocurre al combinar la nueva versión de Java en Snow Leopard con las clases compiladas por el compilador de JDT (yo uso Eclipse 3.5 todavía... quizá con el nuevo Eclipse 3.6 esto no pase...).

Yo lo he solucionado haciendo que -Xms y -Xmx coincidan y poniendo suficiente PermGenSpace (aunque eso es otra guerra), tanto para Eclipse como para el lanzador de Junit.

Lo "bueno" de todo esto es que desde línea de comandos todo funciona (ya que no se usa el compilador de JDT).

Otras solución que he leído (pero no probado) es ejecutar java en modo interpretado (bastante más lento).

Solr logo Sigo encontrando problemas al procesar volúmenes de información importantes con ruby y su ecosistema. Estamos hablando de algo más de dos millones y medio de registros... no es para tanto ¿no?

En este caso el síntoma es la muerte de ruby por falta de memoria durante la reconstrucción del índice de solr (un servidor para búsquedas de texto) con acts_as_solr (un plugin de rails para utilizar solr con active record).

AbelBook:triptance amuino$ rake solr:reindex
(in /Users/amuino/dev/triptance/svn/trunk/triptance)
Clearing index for City...
Rebuilding index for City...
ruby(7890,0xa0398720) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
ruby(7890,0xa0398720) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
ruby(7890,0xa0398720) malloc: *** mmap(size=1052672) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
ruby(7890,0xa0398720) malloc: *** mmap(size=1052672) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
rake aborted!
failed to allocate memory

Un poco de google me descubre que no soy el primero, aunque sí que soy muy raro...

Como tengo bastante más soltura con java que con ruby, vuelvo a ejecutar la tarea con jruby y a analizar el consumo de memoria con jconsole. Un beneficio añadido es que la JVM me permite limitar la memoria y puedo reproducir los errores mucho más rápido (ruby sólo falla cuando el operativo no puede asignar más memoria... después de asignar los 64Gb de memoria virtual).

Tras mucho ensayo y error, parece que el consumo de memoria está estabilizado...

Estos son los cambios:

  • Leer los modelos como :readonly
  • Evitar crear un nuevo array con la versión solrizada de los modelos
  • Organizar el código para que todo siga funcionando

Es decir:

acts_as_solr/lib/class_methods Línea 204 y siguientes...

   def rebuild_solr_index(batch_size=0, &finder)
      finder ||= lambda { |ar, options| ar.find(:all, options.merge({:order => self.primary_key})) }
      start_time = Time.now

      if batch_size > 0
        items_processed = 0
        limit = batch_size
        offset = 0
        begin
          iteration_start = Time.now
          items = finder.call(self, {:limit => limit, :offset => offset, :readonly => true})
          items_processed += items.size
          last_id = items.last.id if items.last
          offset += items.size

          items.collect! { |content| content.to_solr_doc }
          if items.size > 0
            solr_add items
            solr_commit
          end
    
          time_so_far = Time.now - start_time
          iteration_time = Time.now - iteration_start         
          logger.info "#{Process.pid}: #{items_processed} items for #{self.name} have been batch added to index in #{'%.3f' % time_so_far}s at #{'%.3f' % (items_processed / time_so_far)} items/sec (#{'%.3f' % (items.size / iteration_time)} items/sec for the last batch). Last id: #{last_id}"
        end while items.nil? || items.size > 0
      else
        items = finder.call(self, {})
        items.each { |content| content.solr_save }
        items_processed = items.size
      end
      solr_optimize
      logger.info items_processed > 0 ? "Index for #{self.name} has been rebuilt" : "Nothing to index for #{self.name}"
    end

De nuevo, espero que esto le ahorre a alguien un poco de tiempo

Esta es la línea de comandos final...

jruby --server -J-Xmx1024m -w -S rake solr:reindex CLEAR=true BATCH=500

Y este, el consumo de memoria...

Consumo de memoria después de modificar acts_as_solr

1

Sobre mi

No hay sorpresas, mi nombre es Abel Muiño. Soy un apasionado del desarrollo de software desde que cayó en mis manos un ZX Spectrum 48K... si no recuerdo mal, tendría unos 7 años. Han pasado bastantes años, varias empresas y...

Comentarios recientes

  • @Manuel: tienes toda la razón sobre el "efecto contagio". Durante estas vacaciones hablaba del tem...

  • Germán: creo que tengo el mismo joystick de la foto en algún cajón en casa de mi padre ;-) Sobre tu...

  • Hola Abel: Está claro que Dios los cría y ellos se juntan. De ahí que siga tu blog, porque comparto...

    Manuel Jesús Recena Soto
    My most authentic self
  • Uff da miedo conocer tanta gente parecida, hace poco publiqué esta foto: http://twitpic.com/2c90t7...

  • No hombre! Gracias a ti que le subes el nivel a este pobre blog! Estoy de acuerdo en que no siempre...

Cerrar