performance - Can I allocate objects contiguously in java? -
assume have large array of relatively small objects, need iterate frequently.
i optimize iteration improving cache performance, allocate the objects [and not reference] contiguously on memory, i'll fewer cache misses, , overall performance segnificantly better.
in c++, allocate array of objects, , allocate them wanted, in java - when allocating array, allocate reference, , allocation being done 1 object @ time.
i aware if allocate objects "at once" [one after other], jvm most likely allocate objects contiguous can, might not enough if memory fragmented.
my questions:
- is there way tell jvm defrag memory before start allocating objects? enough ensure [as possible] objects allocated continiously?
- is there different solution issue?
new objects creating in eden space. eden space never fragmented. empty after gc.
the problem have when gc performed, object can arranged randomly in memory or surprisingly in reverse order referenced.
a work around store fields series of arrays. call column-based table instead of row based table.
e.g. instead of writing
class pointcount { double x, y; int count; } pointcount[] pc = new lots of small objects.
use columns based data types.
class pointcounts { double[] xs, ys; int[] counts; }
or
class pointcounts { tdoublearraylist xs, ys; tintarraylist counts; }
the arrays in 3 different places, data otherwise continuous. can marginally more efficient if perform operations on subset of fields.
public int totalcount() { int sum = 0; // counts continuous without between values. for(int i: counts) sum += i; return i; }
a solution use avoid gc overhead having large amounts of data use interface access direct or memory mapped bytebuffer
import java.nio.bytebuffer; import java.nio.byteorder; public class mycounters { public static void main(string... args) { runtime rt = runtime.getruntime(); long used1 = rt.totalmemory() - rt.freememory(); long start = system.nanotime(); int length = 100 * 1000 * 1000; pointcount pc = new pointcountimpl(length); (int = 0; < length; i++) { pc.index(i); pc.setx(i); pc.sety(-i); pc.setcount(1); } (int = 0; < length; i++) { pc.index(i); if (pc.getx() != i) throw new assertionerror(); if (pc.gety() != -i) throw new assertionerror(); if (pc.getcount() != 1) throw new assertionerror(); } long time = system.nanotime() - start; long used2 = rt.totalmemory() - rt.freememory(); system.out.printf("creating array of %,d used %,d bytes of heap , tool %.1f seconds set , get%n", length, (used2 - used1), time / 1e9); } } interface pointcount { // set index of element referred to. public void index(int index); public double getx(); public void setx(double x); public double gety(); public void sety(double y); public int getcount(); public void setcount(int count); public void incrementcount(); } class pointcountimpl implements pointcount { static final int x_offset = 0; static final int y_offset = x_offset + 8; static final int count_offset = y_offset + 8; static final int length = count_offset + 4; final bytebuffer buffer; int start = 0; pointcountimpl(int count) { this(bytebuffer.allocatedirect(count * length).order(byteorder.nativeorder())); } pointcountimpl(bytebuffer buffer) { this.buffer = buffer; } @override public void index(int index) { start = index * length; } @override public double getx() { return buffer.getdouble(start + x_offset); } @override public void setx(double x) { buffer.putdouble(start + x_offset, x); } @override public double gety() { return buffer.getdouble(start + y_offset); } @override public void sety(double y) { buffer.putdouble(start + y_offset, y); } @override public int getcount() { return buffer.getint(start + count_offset); } @override public void setcount(int count) { buffer.putint(start + count_offset, count); } @override public void incrementcount() { setcount(getcount() + 1); } }
run -xx:-usetlab
option (to accurate memory allocation sizes) prints
creating array of 100,000,000 used 12,512 bytes of heap , took 1.8 seconds set , get
as off heap, has next no gc impact.
Comments
Post a Comment