代码之家  ›  专栏  ›  技术社区  ›  non sequitor

Java中的垃圾收集器转换

  •  3
  • non sequitor  · 技术社区  · 15 年前

    最近,我听到柯克·佩珀代因(Kirk Pepperdine)说要改变垃圾收集器以获得更好的性能——但这究竟意味着什么?是什么让一个垃圾收集器比另一个更好或不同?

    3 回复  |  直到 15 年前
        1
  •  6
  •   CPerkins    15 年前

    你会问两个问题:

    为了更好的性能,在Java中更改垃圾收集器意味着什么?

    这是一个巨大的话题,和其他一些回应者一样,我敦促你们阅读一些文章。我推荐 Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning 来自太阳。下面的信息主要来自那里。在另一个答案中推荐的“涡轮增压”Java文章更老了。

    简而言之,在运行JVM时,我们有许多选择之一是选择一个垃圾收集器,目前有三个:

    • 串行收集器(使用-xx:+useserialgc选项选择)-它使用一个线程来完成所有收集工作,并且所有的工作都在发生时等待。
    • 并行收集器(使用-xx:+useparallelgc选项选择)-它并行执行次要集合(年轻一代),但所有内容都在主要集合期间等待。
    • 并发收集器(使用-xx:+useconcmarkswepgc选项选择)-这允许在应用程序运行时执行大多数收集操作。

    是什么让一个垃圾收集器比另一个更好?

    您的应用程序可以。每个垃圾收集器都有一个“最佳位置”——一系列的应用程序配置文件,对于这些应用程序配置文件,它是最优秀的收集器。

    首先,要知道虚拟机非常擅长为您选择一个收集器,并且与大多数优化一样,在确定应用程序的性能不好并且垃圾收集可能是罪魁祸首之前,您不应该考虑对其进行二次猜测。

    在这种情况下,您必须问以下问题:1)您的应用程序是在单处理器机器上运行,还是在多处理器机器上运行?2)您更关心“最小化暂停时间”还是“最大化吞吐量”?也就是说,如果您必须在应用程序从不暂停但总体上完成的工作更少与总体上完成的工作更多之间进行选择,而是不时暂停,您会选择哪一个?

    大致来说,作为一个起点:

    • 在一 多个 -处理器机器,主要涉及 最小化暂停时间 你会倾向于使用 同时发生的 收集器(考虑启用增量模式)
    • 在一 多个 -处理器机器,主要涉及 最大化吞吐量 你会倾向于使用 平行 收集器(考虑启用并行压缩)
    • 在A上 单一的 -处理器机器,带 小数据集 (高达大约100MB),您将倾向于使用 系列 收藏家
    • 在一 单一的 -处理器机器,主要涉及 最大化吞吐量 你会倾向于使用 系列 收藏家
    • 在一 单一的 -处理器机器,主要涉及 最小化暂停时间 你会倾向于使用 同时发生的 收集器(考虑启用增量模式)

    不过,同样,虚拟机在为您选择收集器方面做得很好,最好不要覆盖它,除非并且直到您发现它对于您的应用程序来说还不够好。

        2
  •  2
  •   reccles    15 年前

    一些收集器的吞吐量更好,其他收集器的响应时间更好。区别通常在于收集器选择暂停应用程序的方式。有些像CMS在停止应用程序之前使用多个通行证来分类垃圾。这种分类可以在应用程序运行时在后台线程中进行,因此不会像“停止世界”执行GC那样干扰应用程序。

    编辑

    退房 this document by sun . 另外,大约一半的地方有一个不错的图像,显示了默认的MarkCompactCollector与CMS Collector的对比。一张图片胜过千言万语,但这篇文章也是一篇很好的读物;)同样值得一读的是新的g1收集器上的所有文档。

        3
  •  1
  •   Thorbjørn Ravn Andersen    15 年前

    基本的问题是Java程序看到内存的方式(你称之为“新MyObjor”,并且它是存在的,当你完成它时,你就忘了它)并不能很好地映射到底层的操作系统和硬件。

    垃圾收集器的工作是识别那些不被对象使用的内存区域,并将它们“融合”在一起,以提供一个大的内存区域,从中可以分配新对象。在Java规范中,这是非常模糊的措辞,如何做到这一点,最有可能是为了为这个重要任务的设计者提供最大的灵活性。

    有几种方法,各有优缺点。您通常需要的是一个垃圾收集器,它可以在后台跟上被放弃对象的速度,因为它唯一能赶上的方法是在赶上时停止程序。这会带来非常糟糕的用户体验。

    Java对象的一个典型趋势是它们生存很短的时间(当前块或方法)或很长的时间。现代的垃圾收集器通过拥有多个池来处理这一问题,从而使年轻对象的处理方式不同于旧对象。