2010-11-04 6 views
8

Estoy usando MappedByteBuffer para acelerar las operaciones de lectura/escritura de archivos(). Mis preguntas como abajo:¿Necesitamos usar MappedByteBuffer.force() para vaciar datos en el disco?

  1. no estoy seguro si necesito utilizar el método .force() para volcar el contenido en el disco o no. Parece que sin .force(), el .getInt() todavía puede funcionar perfectamente (bueno, dado que se trata de un búfer mapeado en memoria, supongo que .getInt() busca los datos del disco, lo que significa que los datos se han descargado a ya disco.

  2. es el método .force() un método de bloqueo?

  3. es un método de bloqueo de un bloque sincronizado?

  4. Hay una gran diferencia de rendimiento con o sin llamar .force () Método: ¿Cuál es el beneficio de llamar a .force() manualmente? ¿Bajo qué situación deberíamos usar? Supongo que, sin llamarlo, los datos se escribirán en el disco detrás de la escena.

  5. Si necesitamos llamar a .force(), ¿lo llamará desde otro subproceso para mejorar el rendimiento? ¿Corromperá los datos debido a un problema de sincronización?

    import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode;

public class Principal {

public static void main(String[] args) throws IOException { 
    System.out.println("start"); 

    RandomAccessFile raf = new RandomAccessFile("test.map", "rw"); 
    FileChannel fc = raf.getChannel(); 
    MappedByteBuffer mbb = fc.map(MapMode.READ_WRITE, 0, 2000000); 

    int total = 0; 
    long startTime = System.currentTimeMillis(); 
    for (int i = 0; i < 2000000; i += 4) { 
     mbb.putInt(i, i); 
     //mbb.force(); 
     total += mbb.getInt(i); 
    } 
    long stopTime = System.currentTimeMillis(); 

    System.out.println(total); 
    System.out.println(stopTime - startTime); 
    System.out.println("stop"); 
} 

}

+0

¿Versión del JDK? (No es que realmente haya cambiado tanto) –

+0

No veo qué diferencia haría. – EJP

+0

Ninguno después de mirar el Javadoc :-) –

Respuesta

3
  1. Debe llamar sólo si usted tiene requisitos transaccionales extremas, es decir, va a implementar una base de datos. getInt() lee desde la memoria: el sistema operativo pagina el archivo dentro y fuera de esa memoria.

  2. No está especificado.

  3. Los métodos se sincronizan si así se especifica. No tiene nada que ver con si bloquean o no.

  4. See (1). Los datos seguirán escribiéndose, pero según el capricho del sistema operativo en lugar del tuyo.

  5. Lo dudo, pero vea (2), y dudo que deba llamarlo, vea (1).

+0

Gah, debería haber visto su respuesta en primer lugar, se disculpa por decir más o menos lo mismo :). –

+0

Tengo una pregunta, si no llamo a force(), ¿hay alguna operación io para ese archivo cuando llamo a putInt o getInt? – Jaskey

2

bien, tomar mi respuesta con un grano de sal (no soy un experto en NIO)

1.) El putInt(i, i) va a escribir en el MappedByteBuffer (MBB) que está en la memoria y el funcionamiento El sistema transfiere ese valor al archivo subyacente real (test.map) cuando lo desea.

El uso de force() indica al sistema operativo que transfiera los datos 'ahora' (lo que puede ser útil si tiene otro proceso que necesita leer de ese archivo).

Su getInt(i) es la lectura del valor de la MappedByteBuffer (MBB), si se utiliza force() en la forma en que son entonces usted sabe que bajo el capó de su archivo está en sincronía con ese búfer de memoria).

Lo más probable es que no es necesario utilizar force()

2.) No estoy seguro, yo creo es como el Java 7 NIO.2 cosas empieza a aludir a ser capaz de hacer este tipo de cosas de una manera no bloqueante. Todavía estoy investigando eso en este momento.

3.) Estas son dos preocupaciones separadas. Recomiendo echar un vistazo al libro de Doug Lea :-).

4.) Como 1.) states, force() le dirá al sistema operativo que escriba 'ahora', de lo contrario, el sistema operativo escribe cuando le da la gana.

+0

Tengo una pregunta que, cuando la fuerza se está ejecutando, ¿algún efecto en putInt()? , ¿pone int tiene que esperar que force() complete o 'force()' tiene impacto en putInt()? – Jaskey

1

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6816049

fuerza() es inútil en Windows. Bicho bastante aterrador.

+0

Además del comentario/respuesta de Yao de que la implementación fue lo suficientemente buena para la mayoría de los usuarios, el error vinculado ya se ha corregido en JRE 7 build 118, las JVM actuales no se ven afectadas. –

3

MappedByteBuffer.force() es no inútil en Windows. Utilicé la herramienta "Process Monitor" desde http://technet.microsoft.com/en-us/sysinternals/bb896645 para controlar el acceso al archivo. De acuerdo con el registro, MappedByteBuffer.force() llamará inmediatamente a API API WriteFile() en Modo síncrono sin memoria caché. La fiabilidad debería ser similar a la de FileChannel.force() que llamará a la API de Windows FlushFileBuffers() inmediatamente para escribir el archivo. Por lo tanto, MappedByteBuffer.force() es lo suficientemente confiable para la mayoría de los tipos de usos. Probado en Windows 7 64bit con Java 1.6.0_24.

+1

Esto no proporciona una respuesta a la pregunta. Para criticar o solicitar aclaraciones de un autor, deje un comentario debajo de su publicación. - [De la crítica] (/ review/low-quality-posts/10941104) – AtheistP3ace

+0

No tuve derecho a agregar un comentario debajo de una publicación cuando escribí esta publicación. Es por eso que creé una nueva publicación. – Yao

Cuestiones relacionadas