如何显式地执行垃圾回收

9

Java内置垃圾回收机制,允许开发人员创建新对象而无需明确考虑内存分配和释放,因为垃圾回收器会自动回收可重用的内存。

据我所知,当应用程序耗尽内存时,垃圾回收器通常会运行。它持有表示对象之间链接的图形,并可以释放孤立的对象。

虽然我们有System.gc(),但如果您在代码中编写System.gc(),Java VM可能会在运行时决定是否在该点进行垃圾回收,如此帖子所述:Java中的System.gc()

因此,我对Java的垃圾回收过程有一些疑问。

  • 我想知道Java中是否有类似于C语言中的free()方法,我们可以在需要明确释放由new操作符分配的内存时调用它。

  • new操作是否执行与malloc()calloc()相同的操作?

  • 在Java中是否有delete()free()malloc()calloc()sizeof()方法的替代方法。


1
Java能够处理所有的事情... 关于内存管理,如果没有严重问题,你几乎无法做什么。只需要确保所有的引用都为null,垃圾回收器就会发挥它的作用。 - initramfs
3
如果您需要自己管理内存,那么Java不是适合您的技术。如果您只是想要自己管理内存,那么您应该先弄清楚您是否真的需要这样做。对于大多数应用程序来说,您并不需要这样做。 - linac
4个回答

7

不,没有。Java不是C语言,你不应该显式地管理内存。


4
请根据问题提供一些解释。 - Sahil Mahajan Mj
2
虽然您提供了一个简短但非常好的答案,但这个我已经知道。这就是为什么我发布这个问题来了解它如何被管理,因为可能存在一些关键的内存应用。但无论如何还是谢谢。 - Sahil Mahajan Mj
您可以通过JVM和GC配置间接地管理内存。但是,您不应该以显式的方式这样做。 - Andres

6
据我所知,垃圾回收器通常在您的应用程序耗尽内存时运行。对此有些不同意见,它是异步运行并收集引用的内存位置。
我想知道在Java中是否有类似于C语言中的free()方法,我们可以在显式地释放new运算符分配的内存部分时调用它。
再次提到System.gc()是您的选择,但不能保证内存立即清除。
如果您指的是分配内存,则对于Object来说是相同的操作。
据我所知,Java中没有直接的函数来执行这样的操作。就我而言,您不必担心这些事情,现代JVM足够聪明,可以处理这些事情。这里有一个关于GC何时运行的有趣的SO线程,希望能帮助您。

1
我会提到finalize(),但是我们永远不应该使用它。 - initramfs
+1 很好,但如果您能提供一些关于何时执行System.gc()垃圾回收的解释会更好。 - Sahil Mahajan Mj
2
@CPUTerminator finalize 不会释放内存。它执行对象在其内存被释放之前需要完成的任何操作。 - Cruncher
newmalloc()根本不相似,它要轻量得多。我记得在现代JIT上,new Object()编译成了八个机器指令-与需要数百条指令的malloc()相比,可以看出差别明显。 - ntoskrnl
@Cruncher 嗯,好的...我以为这是gc用来清理内存的方法。 - initramfs
@CPUTerminator finalize 是修复损坏状态的最后尝试。关闭程序应该关闭但未关闭的流、文件和套接字,或释放 AWT 中的本机窗口句柄等。这发生在不同的线程中,没有保证的顺序,也没有保证何时甚至是否调用它们。finalize 还会减慢 GC 的速度,因为具有 finalize 的对象必须排队运行它,不能立即清理。 - josefx

1
我没有特别地从事过这个领域,但我阅读了一些关于Java NIO的知识增广。在NIO中,我们有一个ByteBuffer,它似乎可以是Java版本的malloc。 缓冲区本质上是一个内存块,您可以将数据写入其中,然后稍后再次读取。这个内存块被包装在一个NIO缓冲区对象中,该对象提供了一组方法,使得更容易使用内存块。 语法:
ByteBuffer buf = ByteBuffer.allocate(24);

更多阅读请参见ByteBuffer

没错,但它与 new byte[24]new ArrayList(24) 并没有太大的区别。你不能释放 ByteBuffer 的内存,它也不是“通用内存”,例如,你不能将其用于对象。 - maaartinus
我们可以使用直接的ByteBuffer,然后使用Cleaner来释放内存。如果我说错了,请纠正我。 - Helios

0
在Java中,我们有System.gc(),它基本上用于显式地调用垃圾回收。但是,应该潜在地避免使用它,因为它显示了未填充的间隙。 您可以查看这个链接:stackoverflow 然而,当系统内存不足时,Java会自行执行垃圾回收任务。您在应用程序级别上所能做的就是将所有未使用的变量和对象赋值为null,使它们无法使用,并允许JVM执行垃圾回收。

是的,这就是为什么有时会避免使用System.gc()。但是将未使用的变量赋值为null是否保证垃圾收集器一定会在那个点被调用呢? - Sahil Mahajan Mj
嗨Sahil,不,它不能保证垃圾收集器会被调用。只是说,当垃圾收集器在运行时,它使对象有资格被从内存中清除。 - Bhaskar
@SahilMahajanMj:不,这实际上是无关的。但你可能很幸运,JVM 可以发现该对象仅在方法调用期间存在,并将其分配到堆栈上。并非每个 JVM 都会这样做,也没有保证。你不能依赖它,也不需要关心它。 - maaartinus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接