开发者

Dynamic Memory Handling Java vs C++

I am a C++ programmer currently trying to work on Java. Working on C++ I have an habit of keeping track of dynamic memory allocations and employing various techniques like RAII to avoid memory leak. Java as we know provides a Garbage Collector(GC) to take care of memory leaks.So while programing in Java should one just let go all the wholesome worries of heap memory and leave it for GC to take care of the memory leaks or should one have a approach similar to that while programming languages without GC, try to take care of the memo开发者_如何学JAVAry you allocate and just let GC take care of ones that you might miss out. What should be the approach? What are the downsides of either?


I'm not sure what you mean by trying to take care of the memory you allocate in presence of a GC, but I'll try some mind reading.

Basically, you shouldn't "worry" about your memory being collected. If you don't reference objects anymore, they will be picked up. Logical memory leaks are still possible if you create a situation where objects are referenced for the rest of your program (example: register listeners and never un-register them, example: implementing a vector-like collection that doesn't set items to null when removing items off the end).

However, if you have a strong RAII background, you'll be disapointed to learn that there is no direct equivalent in Java. The GC is a first-class tool for dealing with memory, but there is no guaranteed on when (or even if) finalizers are called. This means that the first-class treatment applied to memory is not applied to any other resource, such as: windows, database connections, sockets, files, synchronization primitives, etc.


With Java and .net (and i imagine, most other GC'ed languages), you don't need to worry much about heap memory at all. What you do need to worry about, is native resources like file handles, sockets, GUI primitives like fonts and such. Those generally need to be "disposed", which releases the native resources. (They often dispose themselves on finalization anyway, but it's kinda iffy to fall back on that. Dispose stuff yourself.)


With a GC, you have to:

  • still take care to properly release non-memory resources like file handles and DB connections.
  • make sure you don't keep references to objects you don't need anymore (like keeping them in collections). Because if you do that, you have a memory leak.

Apart from that, you can't really "take care of the memory you allocate", and trying to do so would be a waste of time.


Technically you don't need to worry about cleaning up after memory allocations since all objects are properly reference counted and the GC will take care of everything. In practice, an overactive GC will negatively impact performance. So while Java does not have a delete operator, you will do well to reuse objects as much as possible.

Also Java does not have destructors since objects will exists until the GC gets to them,. Java therefore has the finally construct which you should use to ensure that all non-memory related resources (files sockets etc) are closed when you are finished with them. Do not rely on the finalise method to do this for you.


In Java the GC takes care of allocating memory and freeing unused memory. This does not mean you can disregard the issue alltogether.

The Java GC frees objects that have are not referenced from the root. This means that Java can still have memory leaks if you are not carefull to remove references from global contexts like caches in global HashMaps, etc.

If any cluster of objects that reference eachother are not referenced from the root, the Java GC will free them. I.e. it does not work with reference counts, so you do not need to null all object references (although some coding styles do prefer clearing references as sonn as they are not needed anymore.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜