立即从堆中删除一个对象

Deleting an object from the heap immediately

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

是否可以调用一个方法来告诉 Java 这个对象不再需要并且现在应该删除?

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

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

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

如果您真的需要这种级别的控制,最好使用不需要垃圾收集器的语言。尝试 C 或 C++。或者生锈。


1 - 有一个 JVM 选项 (-XX:DisableExplicitGC) 可以确定对 System.gc() 的调用是否真的会导致垃圾回收。有关此选项和相关选项的详细信息,请参阅 java 手册条目。

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

很遗憾,您使用的语言有误。 Java 不允许您关闭 GC 并手动管理内存。

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

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

假设您使用的是 Hotspot VM,那么堆被分成称为世代的区域。主要原因是弱世代假说,它基本上说你使用的大多数对象只存在非常非常短的时间。如果对象是在年轻一代(你的数据包很可能是)中收集的,那么收集成本实际上是零,因为它们不需要以任何方式进行处理。 JVM 将监视堆内存使用情况和 运行 每当需要回收 space 以保持您的应用程序 运行ning.

您应该让 JVM 完成它的工作并专注于应用程序逻辑。

我们可以使用不安全的内存分配,但这取决于 OS,昂贵且仅适用于基元而不是对象,或者更好的方法是合并可能变大的对象,我们可以结合这两种方法,但是那太复杂了

无论如何最好看看 visualvm 的负载测试,如果 gc activity 很低我们可能什么都不做,内存通常很便宜