了解 Java 内存管理

Java程序员知道JVM运行垃圾回收器,而System.gc()只是JVM运行垃圾回收器的建议。如果我们使用System.gc(),它不一定会立即运行GC。

如果我误解了Java的垃圾收集器,请纠正我。

除了依赖Java的垃圾回收器之外,还有其他方法可以进行内存管理吗?
如果您打算通过某种有助于管理内存的编程实践来回答问题,请这样做。


答案 1

关于 Java 内存管理,要记住的最重要的事情是“取消”你的引用。

只有未引用的对象才会被垃圾回收。

例如,以下代码中的对象永远不会被收集,并且您的内存将充满,只是什么都不做。

List objs = new ArrayList();
for (int i = 0; i  < Integer.MAX_VALUE; i++) objs.add(new Object());

但是,如果您不引用这些对象...您可以随心所欲地循环,而不会出现内存问题。

List objs = new ArrayList();
for (int i = 0; i  < Integer.MAX_VALUE; i++) new Object();

因此,无论你做什么,请确保你删除了对不再使用的对象的引用(设置引用或清除集合)。null

垃圾回收器何时运行最好留给 JVM 来决定。好吧,除非你的程序即将开始做一些使用大量内存并且速度至关重要的事情,所以你可以建议JVM在进入之前运行GC,因为你可能会收集垃圾并继续进行额外的内存。其他明智的做法是,我个人认为没有理由跑步。System.gc()

希望这有帮助。


答案 2

以下是我当时写的小摘要(我从一些博客中偷走了它,但我不记得从哪里来 - 所以没有参考,对不起)

  1. 在Java中没有手动执行垃圾回收的方法。
  2. Java堆分为三代,以便进行垃圾回收。这些是年轻一代,终身或老一代,以及彼尔姆地区。
  3. 新对象在年轻一代中被创造出来,随后转移到老一代。
  4. 字符串池是在堆的 Perm 区域创建的,垃圾回收可以在 Perm 空间中发生,但取决于 JVM 到 JVM。
  5. 次要垃圾回收用于将对象从伊甸园空间移动到幸存者 1 和幸存者 2 空间,而主要收集用于将对象从年轻一代移动到终身一代。
  6. 每当应用程序发生主要垃圾回收时,线程都会在此期间停止,这将降低应用程序的性能和吞吐量。
  7. 在 Java 6 中的垃圾回收中应用了很少的性能改进,我们通常使用 JRE 1.6.20 来运行我们的应用程序。
  8. JVM 命令行选项,用于设置 Java 堆的起始大小和最大大小。根据我的经验,此参数的理想比例是 1:1 或 1:1.5,例如,您可以同时拥有 1GB 或 –Xms 1.2 GB 和 1.8 GB。-Xms-Xmx–Xmx–Xms

命令行选项:-Xms:<min size> -Xmx:<max size>


推荐