linux - Java MappedByteBuffer performance getting worse and worse when you change the map size continuously -


recently had tests java mappedbytebuffer. found if continuously map same file , read it, time spend in reading getting longer , longer. if didn't change map size, faster use same map size in map size variation test.

i hava file "datafile" in 1gb filled integers.

private final file datafile = new file("~/testfile"); private final int intnum = 1024 * 1024 * 1024 / 4; // 1gb integers  @test public void writefile() throws exception {     dataoutputstream dos = new dataoutputstream(new bufferedoutputstream(new fileoutputstream(datafile)));     (int = 0; < intnum; i++) {         dos.writeint(randomutils.nextint());     }     dos.close(); }  

and method reading it

// read datafile in loop fixed map size private void buffersizeperformancetest(final int buffsize) throws exception {     stopwatch stopwatch = stopwatch.createstarted();     filechannel fc = new randomaccessfile(datafile, "r").getchannel();     mappedbytebuffer buffer;     final int readperloop = buffsize / 4;     int currentlen = 0;     int readcount = 0;     (int = 1; ; i++) {         int i1 = * buffsize;         if (i1 >= datafile.length()) {             buffer = fc.map(filechannel.mapmode.read_only, currentlen, datafile.length() - currentlen);             (int j = 0; j < readperloop; j++) {                 buffer.getint();                 readcount++;             }             break;         } else {             buffer = fc.map(filechannel.mapmode.read_only, currentlen, buffsize);             currentlen = i1;         }          (int j = 0; j < readperloop; j++) {             buffer.getint();             readcount++;         }     }     fc.close(); //        bytebufferutil.releasebytebuffer(buffer); //        system.gc();     system.out.println("readcount : " + readcount + " raf buffer size " + getmbytes(buffsize) + " mb : " + stopwatch.elapsed(timeunit.milliseconds)); } 

the variation buffsize test

private static int getmbytes(int bytes) {     return bytes / 1024 / 1024; }  // power of 2 n private static int getm(int n) {     return (int) (math.log10(n) / math.log10(2)); }  @test public void testbuffsizereadperformance() throws exception {     system.out.println(managementfactory.getruntimemxbean().getname());     (int = 0; <= getm(1024); i++) {         thread.sleep(1000);         buffersizeperformancetest((int) (math.pow(2, i) * 1024 * 1024));     } } 

variation outputs:

14071@liuzhmacbook.local readcount : 268435456 raf buffer size 1 mb : 122 readcount : 268435456 raf buffer size 2 mb : 133 readcount : 268435456 raf buffer size 4 mb : 29 readcount : 268435456 raf buffer size 8 mb : 35 readcount : 268435456 raf buffer size 16 mb : 38 readcount : 268435456 raf buffer size 32 mb : 124 readcount : 268435456 raf buffer size 64 mb : 241 readcount : 268435456 raf buffer size 128 mb : 456 readcount : 268435456 raf buffer size 256 mb : 1086 readcount : 268435456 raf buffer size 512 mb : 2458 readcount : 268435456 raf buffer size 1024 mb : 4952 

the fixed buffsize test:

@test public void testbuffsizereadperformance2() throws exception {     system.out.println(managementfactory.getruntimemxbean().getname());      (int = 0; < 10; i++) {         buffersizeperformancetest(1024 * 1024 * 1024);     } } 

output

14157@liuzhmacbook.local readcount : 268435456 raf buffer size 1024 mb : 127 readcount : 268435456 raf buffer size 1024 mb : 111 readcount : 268435456 raf buffer size 1024 mb : 20 readcount : 268435456 raf buffer size 1024 mb : 17 readcount : 268435456 raf buffer size 1024 mb : 23 readcount : 268435456 raf buffer size 1024 mb : 19 readcount : 268435456 raf buffer size 1024 mb : 21 readcount : 268435456 raf buffer size 1024 mb : 22 readcount : 268435456 raf buffer size 1024 mb : 20 readcount : 268435456 raf buffer size 1024 mb : 33 

as 2 tests shows, time spent in reading same buffsize(1024mb) quite different in 2 tests. test fixed buffsize faster variation test.

my question is: 1. how happened, why faster? 2. mappedbytebuffer occupy physical memory? see in activitymonitor, not occupy physical memory.

thanks

----- update -----

the release buffer code:

public static void releasebytebuffer(bytebuffer buffer) throws nosuchfieldexception, illegalaccessexception {     cleaner cleaner = ((directbuffer) buffer).cleaner();     cleaner.clean(); } 

i don't think cause of problem memory usage. because has same output if turn on release code , gc code. anyway, if memory usage, set loop times 100 in second test, should use more memory first test, it's faster first one.

----- update 2 -----

if turn buffsize decrease instead of increase in test 1, problem disappear.

@test public void testbuffsizereadperformance3() throws exception {     system.out.println(managementfactory.getruntimemxbean().getname());     (int = getm(1024); >= 0; i--) {         buffersizeperformancetest((int) (math.pow(2, i) * 1024 * 1024));     } } 

output:

16651@liuzhmacbook.local readcount : 268435456 raf buffer size 1024 mb : 101 readcount : 268435456 raf buffer size 512 mb : 187 readcount : 268435456 raf buffer size 256 mb : 31 readcount : 268435456 raf buffer size 128 mb : 30 readcount : 268435456 raf buffer size 64 mb : 36 readcount : 268435456 raf buffer size 32 mb : 37 readcount : 268435456 raf buffer size 16 mb : 37 readcount : 268435456 raf buffer size 8 mb : 32 readcount : 268435456 raf buffer size 4 mb : 44 readcount : 268435456 raf buffer size 2 mb : 34 readcount : 268435456 raf buffer size 1 mb : 55 

you aren't 'changing map size continuously'.you keep creating new maps, , there no mechanism whereby mappings released, including gc, using more , more memory.

you should aim use few mappedbytebuffers possible, may mean need make sizes larger well.

i don't know bytebufferutil.releasebytebuffer(buffer) does, or comes from, these things of nature cannot reliable.


Comments

Popular posts from this blog

PySide and Qt Properties: Connecting signals from Python to QML -

c# - DevExpress.Wpf.Grid.InfiniteGridSizeException was unhandled -

scala - 'wrong top statement declaration' when using slick in IntelliJ -