create and use a temporary heap

I'm developing a game in java, which is basically updated every 1/60 second. During such an update lots of data is created, passed around and then left unreferenced, lets call this data DTO's. To my understanding, the JVM and the OS stores this data on the program's heap. the heap thus builds up, until the JAVA GC gets to run, which analyses marks all unreferenced data as free and ready to be reused.

Now, the way I see it, this is unnecessary and prone to occasional lag. The way I would like to solve the problem is to have an allocated chunk of memory to use as a temporary heap. This heap is used to store all the temporary stuff that I create and pass around during the update interval. And once I've reached the end of my update, there is no need for any analysis, but I can simply say that the whole chunk is free, and that way reuse the same heap-space update after update. Kind of like tail-recursive stack frames.

Another solution, would be to only use mutable DTO objects and allocate a bunch of them and just reuse them, but I like to take advantage of the advantage to make things as immutable as possible.

This is an effort to illustrate what I mean with code:

void start(){
    Data data = System.allocateDatainMb(500); //allocate 500Mb of virtual  memory
    MagicHeap() mh = System.createAMagicHeap(data); //make a heap of it
    mh.use(); //set all constructors to allocate on this heap

    while(true){
        update();
        mh.clear();
    } 
}

void update(){
    TmpData dto = Gamesystem.createALargePieceOfTemporaryData();
    someClass.doUpdateStuff(dto);
}  

I'm not too familiar with how Java manages memory, but I hope you get my meaning.

Is it possible to some extent?


I might miss something but I'm pretty sure you can't do that in Java as it would interfere with Java's own memory management. After all, Java is meant to shield the user from low-level memory management routines.

Thus I'd suggest going for the DTO pool approach you mentioned. One way to improve that might be to hide the mutators (eg setters and other mutating methods) and only allow factory methods etc. to access them (eg by using package private visibility). Then have factories that create/reuse seemingly immutable instances and manage the pools. You could even handle temporary "overflow", ie when you'd need more instances of some DTO than the pool actually provides.

However, if you think carefully you'll probably find a lot of objects you deem short-lived to actually have longer life cycles if they are used correctly. It's probably just intermediate results of some calculation (like vector/matrix math) that you don't need in the next frame but those can often be discarded right after creating them and could also be avoided in some cases (eg if you use primitives manually or have multable intermediate objects).


What you are trying to do is outsmart the JVM. This is not what you want to be doing. If you really need to be playing with memory allocation directly, Java is not a suitable language.

Java's GC is optimized to deal with many shortlived objects, it expects to be able to free most things from memory shortly after they are added. Going out of your way to set up some kind of caching system can actually reduce performance, as now these objects can't be freed from memory, meaning the heap will have less space and (FULL) GC pauses will be more frequent. This is in addition to any overhead the caching system itself will produce.

This doesn't mean you should ignore memory concerns with Java however. You should avoid unnecessarily creating objects and more importantly you should avoid holding onto an object reference longer than necessary so that you can allow the GC to clean it up. It would likely also be beneficial to tune the GC to fit your programs needs and ensure that you are using the modern G1 GC.

As with any performance tuning, it's important to actually measure the performance differences of your changes. Going of a hunch of what you think will be faster can lead to you putting in effort and adding complexity for little to no gain, or worse a performance drop. Make sure you have real numbers to back up any performance concerns.

链接地址: http://www.djcxy.com/p/81430.html

上一篇: 如何监控垃圾收集以查看GC'd是什么?

下一篇: 创建并使用临时堆