2009-08-25 8 views
1

Voici continuation_store de Mono Continuations (...). En regardant le code ci-dessous, il apparaît comme si magasin() suit ces deux branches:Mono Continuations - La mémoire ne cesse d'augmenter après le stockage()

  1. cont->saved_stack && num_bytes <= cont->stack_alloc_size
    • utiliser la mémoire directement
  2. autre
    • gc libérer la mémoire utilisée, et créer de la mémoire.

Cependant, la chose étrange est si je l'utilise à plusieurs reprises continuation_store(), l'augmentation d'utilisation de mémoire jusqu'à ce que lors d'une étape plus tard, une énorme opération et laggy GC est fait. Quelqu'un peut-il expliquer pourquoi cela arrive?

Merci

static int 
continuation_store (MonoContinuation *cont, int state, MonoException **e) 
{ 
    MonoLMF *lmf = mono_get_lmf(); 
    gsize num_bytes; 

    if (!cont->domain) 
     *e = mono_get_exception_argument ("cont", "Continuation not initialized"); 
    if (cont->domain != mono_domain_get() || cont->thread_id != GetCurrentThreadId()) 
     *e = mono_get_exception_argument ("cont", "Continuation from another thread or domain"); 

    cont->lmf = lmf; 
    cont->return_ip = __builtin_return_address (0); 
    cont->return_sp = __builtin_frame_address (0); 

    num_bytes = (char*)cont->top_sp - (char*)cont->return_sp; 

    /*g_print ("store: %d bytes, sp: %p, ip: %p, lmf: %p\n", num_bytes, cont->return_sp, cont->return_ip, lmf);*/ 

    if (cont->saved_stack && num_bytes <= cont->stack_alloc_size) 
    { 
     /* clear to avoid GC retention */ 
     if (num_bytes < cont->stack_used_size) 
      memset ((char*)cont->saved_stack + num_bytes, 0, cont->stack_used_size - num_bytes); 
    } 
    else 
    { 
     tasklets_lock(); 
     internal_init(); 
     if (cont->saved_stack) { 
      mono_g_hash_table_remove (keepalive_stacks, cont->saved_stack); 
      mono_gc_free_fixed (cont->saved_stack); 
     } 
     cont->stack_used_size = num_bytes; 
     cont->stack_alloc_size = num_bytes * 1.1; 
     cont->saved_stack = mono_gc_alloc_fixed (cont->stack_alloc_size, NULL); 
     mono_g_hash_table_insert (keepalive_stacks, cont->saved_stack, cont->saved_stack); 
     tasklets_unlock(); 
    } 
    memcpy (cont->saved_stack, cont->return_sp, num_bytes); 

    return state; 
} 

Répondre

1

Remarque l'appel à mono_gc_free_fixed ne fait rien dans le collecteur de Boehm par défaut: https://github.com/mono/mono/blob/master/mono/metadata/boehm-gc.c#L528

La branche else juste la mémoire supprime des keepalive_stacks table de hachage. Cette table de hachage conserve une référence à la mémoire allouée afin qu'elle ne soit pas récupérée. Une fois que le pointeur vers la mémoire allouée est supprimé de cette table de hachage, il sera récupéré lors de la prochaine garbage collection. Cette collection est déclenchée plus tard une fois qu'elle atteint une certaine quantité d'allocation de mémoire.

Questions connexes