0

I am currently coding a server that uses netty, and I have a lot of packets coming in. If I have read the packet I want to delete it out of RAM immediately. This means I don't want to rely on the GC but free the RAM immediately myself. Since the GC only runs once every 5-50 second but my code is much faster and would keep the RAM low.

Is it possible to invoke a method to tell Java that this object is no longer needed and should be deleted now?

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216

4 Answers4

1

You can't delete individual objects from heap immediately in Java.

You could (try to) force a garbage collection to happen1 by calling System.gc(), but it is bad for performance.

You could (try to) manage your objects (e.g. using object pools) so that it is not necessary to run the GC as often, but this makes your program more complicated and limits the libraries that you can make use of. And it doesn't actually free the memory. (Objects that are "freed" are returned to the pool's free list, but if you have too many objects on the free list the only way to reclaim the space is to GC.)

If really you need this level of control, you are better off using a language that doesn't require a garbage collector. Try C or C++. Or Rust.


1 - There is a JVM option (-XX:DisableExplicitGC) that determines whether a call to System.gc() actually causes a garbage collection. Refer to the java manual entry for details of this and related options.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Is it possable to write native code that deletes them like gc, i cant switch the language cince i allready wrote +80K lines in java and i dont want to rewrite all – Julius mauser Nov 28 '18 at 11:32
  • No. It isn't possible. Standard Java GCs and memory allocators are not implemented in a way that would make that feasible. (They don't keep a "free list") – Stephen C Nov 28 '18 at 11:34
  • So the only way is to spam the System.gc() call or use a objekt pool and in every objekt ther must be a clear method? – Julius mauser Nov 28 '18 at 11:36
  • You could spam `System.gc()`, but your application's performance would be atrocious. And using an object pool doesn't actually free memory. Rather it reduces that rate at which object is consumed ... so that you need to GC less often. – Stephen C Nov 28 '18 at 11:36
  • So the best way is to just let it jump between 10-90% ram usage? – Julius mauser Nov 28 '18 at 11:37
  • Yes. That is the best way. – Stephen C Nov 28 '18 at 11:38
  • @Juliusmauser think about it this way: what *actual problem* does “jumping between 10-90% ram usage” cause? If this RAM is truly needed for something else, the garbage collector will run more frequently automatically. – Holger Nov 28 '18 at 13:36
0

This means I dont want to rely on the GC but free the ram immediately myself.

Unfortunately you're using the wrong language if you want to do this. Java doesn't let you turn off the GC and manage memory manually.

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
  • I dont want to turn the GC off, i just want to delete the objekt that use the most ram after im done with using them – Julius mauser Nov 28 '18 at 11:33
  • @Juliusmauser still no way of doing that I'm afraid. You can try to use tricks like setting a reasonably low heap and calling `System.gc()` to try to *encourage* the VM to free things up, and you can use specific collection strategies, but there's never a guarantee. – Michael Berry Nov 28 '18 at 11:34
  • 2
    @Juliusmauser Just forget it. GC can easily handle megabytes per second, so just let it do its job. It doesn't run until needed, so the RAM usage can be high, but this per se means nothing. You only have a problem, when you run out of memory or the GC takes too long; until then you just shouldn't care. – maaartinus Nov 28 '18 at 17:41
0

The question you need to ask yourself is, why do you want to remove a packet object immediately? You say that the GC runs every 5-50 seconds and you want to keep RAM (I assume you mean usage) low.

When writing Java code you should not (really) consider its interaction with the JVM's memory management. When you start your application, a heap size wil be set (either using default values or explicitly via the -Xms/-Xmx command line switches). If the application is handling all of the packets being delivered and the GC overhead (application pause time) is acceptable then your code is working exactly the way it should. You have no reason to want to delete processed packets as the GC is doing that for you.

Assuming you're using the Hotspot VM then the heap is separated into regions called generations. The primary reason for this is the weak generational hypothesis, which basically says that most objects you use only live for a very, very short time. If objects are collected in the young generation (which your packets most likely will be) there is effectively zero cost of collection, since they do not need to be processed in any way. The JVM will monitor heap memory usage and run whenever it is necessary to reclaim space to keep your application running.

You should let the JVM do its job and focus on the application logic.

Speakjava
  • 3,177
  • 13
  • 15
0

we can use unsafe memory allocation but that depends on the OS ,expensive and only for primitives not objects , or a better way is to pool the objects which could go large ,we can combine both methods but that would be too complex

anyway its better take a look on visualvm on load test, if gc activity is low we may not do anything , memory is usually cheap