立即从堆中删除对象

时间:2018-11-28 11:21:48

标签: java garbage-collection ram

我当前正在编码使用netty的服务器,并且有很多数据包进来。如果读取了该数据包,我想立即将其从RAM中删除。这意味着我不想依靠GC而是自己立即释放RAM。由于GC每5-50秒仅运行一次,但是我的代码要快得多,并且可以使RAM保持较低。

是否可以调用一种方法来告诉Java不再需要该对象,现在应该删除它?

4 个答案:

答案 0 :(得分:1)

您不能在Java中立即从堆中删除单个对象。

您可以(通过调用)System.gc()强制进行垃圾收集 1 ,但是它是bad for performance

您可以(尝试)管理对象(例如,使用对象池),这样就不必经常运行GC,但这会使您的程序更加复杂,并限制了您可以使用的库。而且,它实际上不会释放内存。 (“释放”的对象将返回到池的空闲列表中,但是如果空闲列表上的对象太多,则唯一回收空间的方法是使用GC。)

如果确实需要这种级别的控制,那么最好使用不需要垃圾收集器的语言。尝试使用C或C ++。或Rust。


1-有一个JVM选项(-XX:DisableExplicitGC),用于确定对System.gc()的调用是否实际上导致垃圾回收。有关此选项和相关选项的详细信息,请参见java手动输入。

答案 1 :(得分:0)

  

这意味着我不想依靠GC,而是自己立即释放RAM。

不幸的是,如果您要这样做,将使用错误的语言。 Java不允许您关闭GC并手动管理内存。

答案 2 :(得分:0)

您需要问自己的问题是,为什么要立即删除数据包对象?您说GC每5至50秒运行一次,并且您想保持较低的RAM(我假设您是说使用率)。

在编写Java代码时,您不应该(真的)考虑其与JVM的内存管理的交互。启动应用程序时,将设置堆大小(使用默认值或通过-Xms / -Xmx命令行开关显式设置)。如果应用程序正在处理所有传递的数据包,并且可以接受GC开销(应用程序暂停时间),则您的代码将按应有的方式正常工作。您没有理由要删除已处理的数据包,因为GC正在为您这样做。

假设您正在使用Hotspot VM,那么堆将被分成几代。造成这种情况的主要原因是较弱的世代假设,该假设基本上说,您使用的大多数对象只能生存很短的时间。如果对象是在年轻一代中收集的(您的数据包最有可能收集),则收集成本实际上为零,因为它们无需进行任何处理。 JVM将监视堆内存使用情况,并在需要回收空间以保持应用程序运行时运行。

您应该让JVM做好其工作,并专注于应用程序逻辑。

答案 3 :(得分:0)

我们可以使用不安全的内存分配,但这取决于操作系统,昂贵且仅适用于原语而不是对象,或者更好的方法是将可能变大的对象池化,我们可以将这两种方法结合起来,但这太复杂了< /p>

无论如何最好在负载测试中查看visualvm,如果gc活动很低我们可能不会做任何事情,内存通常很便宜