关于java:System.gc()什么时候做

关于java:System.gc()什么时候做

When does System.gc() do anything

我知道垃圾回收在Java中是自动化的。但我明白,如果在代码中编写EDCOX1(0),Java VM可以在运行时决定是否在该点进行垃圾回收。这是如何精确工作的?当虚拟机看到System.gc()时,它究竟基于什么基础/参数决定执行(或不执行)GC?在这种情况下,是否有一些示例可以将其放入代码中?


实际上,它通常决定进行垃圾收集。答案取决于很多因素,比如运行的是哪个JVM,它处于哪个模式,它使用的是哪个垃圾收集算法。

我不会在你的代码中依赖它。如果jvm将要抛出一个ofmemoryError,那么调用System.gc()不会停止它,因为垃圾收集器将在它达到这个极限之前尝试释放尽可能多的内存。我在实践中唯一一次看到它是在IDES中使用的,它连接到一个用户可以点击的按钮上,但即使在那里,它也没有太大的用处。


我能想到的唯一一个调用System.gc()有意义的例子是在分析应用程序以搜索可能的内存泄漏时。我相信在获取内存快照之前,配置程序会调用这个方法。


您无法控制Java中的GC——VM决定。我从来没有遇到过需要System.gc()的案件。由于System.gc()调用只是简单地建议VM进行垃圾收集,而且它还进行完全的垃圾收集(多代堆中的旧代和新代),因此它实际上可以导致消耗比需要更多的CPU周期。

在某些情况下,向虚拟机建议现在进行完全收集可能是有意义的,因为您可能知道应用程序将在接下来的几分钟内处于空闲状态,然后才进行重载提升。例如,在应用程序启动期间初始化了许多临时对象之后(即,我刚刚缓存了大量信息,我知道在一分钟左右的时间内不会有太多活动)。想想一个IDE,比如Eclipse启动——它需要做很多初始化工作,所以可能在初始化之后立即进行完整的GC是有意义的。


Java语言规范不能保证JVM在调用EDCOX1 OR 0时将启动GC。这就是为什么"可能或可能不决定在那个时候进行GC"。

现在,如果您看看OpenJDK源代码,它是OracleJVM的主干,您会发现对System.gc()的调用确实会启动一个GC周期。如果您使用另一个JVM,如J9,则必须检查它们的文档以找出答案。例如,azul的jvm有一个连续运行的垃圾收集器,因此对System.gc()的调用不会做任何事情。

其他一些答案提到在jconsole或visualvm中启动GC。基本上,这些工具对System.gc()进行远程调用。

通常,您不希望从代码开始垃圾收集循环,因为它会扰乱应用程序的语义。您的应用程序做一些业务工作,JVM负责内存管理。您应该将这些关注点分开(不要让您的应用程序做一些内存管理,而要专注于业务)。

但是,很少有情况下调用System.gc()是可以理解的。例如,考虑微基准。没有人想让GC循环发生在微基准的中间。因此,您可以在每个度量之间触发一个GC循环,以确保每个度量从一个空堆开始。


如果你打电话给System.gc(),你需要非常小心。调用它可能会给应用程序增加不必要的性能问题,并且不能保证实际执行集合。实际上可以通过Java参数EDCOX1(6)来禁用显式EDCOX1×0Ω。

我强烈推荐通过Java热点垃圾收集中的文档阅读更多关于垃圾收集的详细信息。


System.gc()由虚拟机实现,它所做的是特定于实现的。例如,实现者可以简单地返回,什么也不做。

至于何时发布手动收集,您可能希望这样做的唯一时间是放弃包含大量较小收集的大型收集--a比如说,Map>,你想尝试在某个时候或者某个地方进行性能测试,但在大多数情况下,你不应该担心。GC比你更了解——遗憾的是——大多数时候。


如果使用直接内存缓冲区,即使直接内存不足,JVM也不会为您运行GC。

如果您调用ByteBuffer.allocateDirect(),并得到一个outofmemoryer错误,您会发现在手动触发GC之后,这个调用是正常的。


大多数JVM将启动GC(取决于-xx:DiableExplicitGC和-xx:+ExplicitgCinvokesConcurrent开关)。但是,为了允许以后更好的实现,规范定义得不太好。

规范需要澄清:bug 6668279:(spec)system.gc()应该表明我们不建议使用,也不保证行为。

在内部,rmi和nio使用gc方法,它们需要同步执行,目前正在讨论:

bug 5025281:允许System.gc()触发并发(而不是停止整个世界)完整集合


我们绝不能强迫垃圾收集。gc只是建议使用vm进行垃圾收集,但是,实际上,机制运行的时间,没有人知道,这是由JSR规范所规定的。


花时间测试各种垃圾收集设置有很多话要说,但是如上所述,这样做通常不有用。

我目前正在研究一个涉及内存有限环境和相对大量数据的项目——有一些大数据块将我的环境推到了极限,即使我能够降低内存使用率,以便理论上它可以正常工作,但我仍然会得到堆空间错误——详细的GC选项。向我展示了它试图收集垃圾,但没有用。在调试器中,我可以执行system.gc(),并确保有足够的"大量"可用内存……不是额外的,而是足够的。

因此,我的应用程序调用System.gc()的唯一时间是它将要进入代码段,在该段中将分配处理数据所需的大缓冲区,并且对可用内存的测试表明我不能保证拥有它。特别是,我正在研究一个1GB环境,其中至少300MB被静态数据占用,其中大部分非静态数据与执行相关,除非正在处理的数据恰好在源位置至少为100-200MB。这都是自动数据转换过程的一部分,所以从长远来看,数据都存在于相对较短的时间内。

不幸的是,虽然可以获得有关调整垃圾收集器的各种选项的信息,但这在很大程度上似乎是一个实验过程,而且不容易获得理解如何处理这些特定情况所需的低级细节。

尽管我使用的是system.gc(),但我仍然继续使用命令行参数进行优化,并设法将应用程序的总体处理时间提高了相当大的一部分,尽管我无法克服处理较大数据块所带来的障碍。也就是说,system.gc()是一个工具……一个非常不可靠的工具,如果你不小心使用它,你会希望它不会经常工作。


EDOCX1·1在EDOCX1·2中是很好的,如果我们正在用Java在桌面/膝上型/服务器上执行软件编码。您可以在Java中调用System.gc()Runtime.getRuntime().gc()

请注意,这些电话都不能保证做任何事情。它们只是建议JVM运行垃圾收集器。无论是否运行GC,都取决于JVM。所以,简短的回答是:我们不知道它何时运行。更长的答案:如果有时间,JVM将运行GC。

我相信,Android也是如此。但是,这可能会减慢系统的运行速度。


当运行显式GC比较好时,我无法想到具体的示例。

一般来说,运行显式GC实际上会造成比好的更多的伤害,因为显式GC将触发一个完整的集合,当它通过每个对象时,会花费更长的时间。如果这个显式GC最终被重复调用,那么很容易导致应用程序速度变慢,因为运行完整GC需要花费大量时间。

或者,如果使用堆分析器遍历堆,并且怀疑库组件正在调用显式GC,则可以将其关闭,将:gc=-xx:+disableexplicitgc添加到jvm参数中。


简而言之:

参数依赖于虚拟机。

示例用法-不能为运行时/生产应用程序考虑一个,但对于某些分析工具(如调用

1
2
3
4
5
6
7
8
// test run #1
test();
for (int i=0; i<10; i++) {
// calling repeatedly to increase chances of a clean-up
  System.gc();
}
// test run #2
test();

如果您想知道是否调用了EDCOX1 0调用,则当JVM执行垃圾收集时,可以使用新的Java 7更新4获取通知。

我不是100%肯定的是,在Java 7更新4中引入了GARBACKECOLCORTERMXBE类,因为我在发行说明中找不到它,但是我在JavaPrimeCutuunnCo站点找到了信息。


通常,在抛出OutOfMemoryException之前,VM会自动执行垃圾收集,因此添加显式调用不应该有帮助,除非它可能会将性能影响移动到更早的时间。

但是,我认为我遇到了一个可能与之相关的案例。但我不确定,因为我还没有测试它是否有任何效果:

当内存映射文件时,我相信map()调用会在没有足够大的内存块时抛出IOException。我认为,在map()文件之前进行垃圾收集可能有助于防止这种情况发生。你怎么认为?


根据Bruce Eckel的Java思想,显式系统.gc-()调用的一个用例是强制终结,即调用终结方法。


当system.gc工作时,它将停止整个世界:所有响应都将停止,垃圾收集器可以扫描每个对象以检查是否需要删除它。如果应用程序是Web项目,所有请求都将停止,直到GC完成,这将导致您的Web项目无法在monent中工作。


推荐阅读

    脚本linux上运行命令?

    脚本linux上运行命令?,工具,代码,时间,密码,系统,环境,名字,位置,第三,下来,t

    linux执行两次命令?

    linux执行两次命令?,系统,信息,连续,名称,命令,初级,首页,工具,管理,终端,lin

    linux命令执行安装?

    linux命令执行安装?,软件,系统,管理,网站,官网,市场,中心,最新,灵活,工作,如

    linux执行一条新命令?

    linux执行一条新命令?,系统,工作,命令,管理,网络,服务,信息,目录,路径,脚本,L

    linux执行c程序命令?

    linux执行c程序命令?,系统,工作,工具,信息,代码,命令,文件,保险,管理,环境,li

    linux命令执行中断?

    linux命令执行中断?,设备,系统,网络,工具,工作,通用,状态,名字,流程,进程,lin

    执行linux脚本命令行?

    执行linux脚本命令行?,工具,位置,地方,环境,数据,状态,暂停,增长,系统,基础,

    linux运行脚本的命令?

    linux运行脚本的命令?,系统,工具,代码,服务,脚本,状态,密码,环境,位置,暂停,l

    linux过滤命令参数?

    linux过滤命令参数?,工具,数据,标准,地址,命令,设备,系统,信息,指令,文件,如

    linux远端执行命令?

    linux远端执行命令?,系统,状态,软件,名称,密码,暂停,网络,环境,认证,在线,如

    linux虚拟机su命令?

    linux虚拟机su命令?,密码,系统,位置,工具,软件,命令,环境,工作,生产,设计,Lin

    linux命令行执行成功?

    linux命令行执行成功?,系统,信息,状态,服务,管理,百度,设计,灵活,代码,命令,L

    安卓执行linux命令行?

    安卓执行linux命令行?,系统,设备,基础,发展,标准,情况,信息,电话,号码,工具,

    c执行在linux命令?

    c执行在linux命令?,系统,环境,保险,工具,代码,命令,程序,文件,终端,语言,如何

    linux下ls命令参数?

    linux下ls命令参数?,时间,系统,数据,命令,文件,信息,标准,密码,工作,名字,lin

    linux执行中退出命令?

    linux执行中退出命令?,档案,状态,命令,分析,数据,电脑,实时,系统,工具,编辑,l

    linux读取命令行参数?

    linux读取命令行参数?,系统,信息,数据,名称,软件,位置,标准,灵活,百度,资料,L

    linux授权命令执行?

    linux授权命令执行?,系统,工作,数字,权限,文件,概念,标准,命令,目录,用户,在L

    linux定时执行命令?

    linux定时执行命令?,时间,系统,服务,任务,工作,标准,情况,周期性,工具,命令,l