2011-03-19 9 views
5

Imagine que tengo una biblioteca C llamada libcat para interactuar con mi gato esponjoso. Por lo tanto, estoy escribiendo enlaces para OCaml para simplificar las interacciones con fluffy.¿Alguna vez OCaml ha copiado bloques personalizados?

module type CAT = sig 
    type cat 
    val find : ... -> cat 
    val feed : cat -> unit 
    ... 
end ;; 
module Cat : CAT = ... 

Existe una considerable gestión de memoria ya está integrado en libcat, como dicen almacenamiento en caché, liberando juguetes destruidos, y tal vez incluso un recolector de basura alcance limitado para vaciar la basura. Sin embargo, en general, libcat requiere que los usuarios liberen explícitamente recursos no utilizados, como juguetes perdidos.

He escrito un apéndice C para Cat.find que encuentra y asigna el gato usando la rutina cat_find de libcat, pero luego almacena el puntero resultante en el gato en un bloque personalizado creado con caml_alloc_custom.

He agregado un método de finalización en la estructura de operaciones personalizadas pasada a caml_alloc_custom. Fundamentalmente, he hecho que este método de finalización libere al gato porque estoy harta de que se rasque la puerta mientras contesto una excepción telefónica.

Ahora estoy preocupado de que, si alguna vez OCaml duplica un bloque personalizado de tipo Cat.cat, a continuación, recolector de basura de OCaml puede liberar esponjosa, mientras que todavía estamos jugando. Por ejemplo:

let fluffy = Cat.find ;; 
fluffy.yodel ;; 
let meow = fluffy ;; 
... 
meow.feed ;; 

Debemos suponer que ... desencadenará recolector de basura de ocaml después de la última referencia explícita a Fluffy, decimos rompiendo platos. ¿Este evento de recolección de basura va a llamar al método de finalización de fluffy y liberarla? ¿O maullarás simplemente se refieren al bloque personalizado original de fluffy, evitando así que se libere el esponjoso?

Imagino que el mullido no se libera en esta situación, pues de lo contrario, OCaml seguramente pediría un método duplicado en la estructura de operaciones personalizadas, pero me pareció mejor preguntarlo. Si esponjoso de hecho podría ser liberado, ¿puedo prevenir esto solo dejando que OCaml la maneje por referencia? Aproximadamente:

type cat_name = real_cat ref 
    type real_cat 

Respuesta

2

El bloque personalizado en sí, es decir, los bytes obtenidos de caml_alloc_custom, es parte de la pila de Caml y se puede mover como cualquier otro object.¹ Es muy común que el bloque personalizado para contener punteros a estructuras de datos a las que también se accede mediante el código C² y que viven fuera del montón de Caml; Caml trata el contenido del bloque personalizado como opaco y ni siquiera sabe si contiene punteros, por lo que no tocará estas estructuras de datos.

Cuando escribe let meow = fluffy, no hay copia: simplemente está dando un nuevo nombre al mismo objeto. Caml nunca duplicará un bloque personalizado; si lo desea, debe proporcionar una primitiva copy_cat en su biblioteca.

¹ Solo el colector de basura menor y el compactador realmente mueven los bloques, el mayor no. Pero eso no es algo en lo que deberías confiar.

² O Fortran, o cualquier otro lenguaje que usa su programa o librería.

Cuestiones relacionadas