如何释放内存在Java中?(How to free memory in Java?)

2019-08-18 02:52发布

是否有一个释放的Java内存,类似于C的方式free()函数? 或者设置对象为null,依靠GC的唯一选择?

Answer 1:

Java使用管理内存,这样你就可以分配内存的唯一方法是通过使用new运营商,并且可以释放内存的唯一途径是依靠垃圾收集器。

这个内存管理白皮书 (PDF)可能有助于解释发生了什么事情。

您也可以拨打System.gc()暗示垃圾收集器立即运行。 然而,Java运行时做出最终决定,而不是你的代码。

按照Java文档 ,

调用gc方法表明Java虚拟机了一些努力,以使他们目前占据可快速重用的内存回收未使用的对象。 当从方法调用控制返回时,Java虚拟机已经从所有丢弃的对象中回收了空间最大的努力。



Answer 2:

似乎没有人提到明确设置对象引用null ,这是一个合法的技术,以“释放”的内存,你可能要考虑。

例如,假设你宣布一个List<String>在上生长的大小是非常大的一个方法的开始,但只需要通过之前的方法一半。 你可以在这一点上设置列表参考null ,让垃圾回收器的方法完成(和引用超出范围反正)前可能回收该对象。

请注意,我很少用在现实中这种技术,但它的价值非常大的数据结构打交道时考虑。



Answer 3:

System.gc(); 

运行垃圾回收器。

调用gc方法表明 Java虚拟机了一些努力,以使他们目前占据可快速重用的内存回收未使用的对象。 当从方法调用控制返回时,Java虚拟机已经从所有丢弃的对象中回收了空间最大的努力。

不建议。

编辑:我写的原始响应在2009年它现在2015年。

垃圾收集器已经得到了在〜20年的Java一直稳步左右更好。 在这一点上,如果你手动调用垃圾收集器,你可能要考虑其他的方法:

  • 如果你强迫机器上数量有限GC,它可能是值得拥有的负载均衡点当前机器,等待它完成投放到连接的客户端,超时一段时间后悬挂的连接,然后就硬-restart的JVM。 这是一个可怕的解决方案,但如果你正在寻找的System.gc(),强制重新启动可能是一个可能的权宜之计。
  • 考虑使用不同的垃圾收集器。 例如,(在过去六年新)G1收集器是一个低暂停模式; 它采用多CPU的整体,但确实也最好从不强迫执行的硬停机。 由于服务器的CPU现在几乎所有拥有多个内核,这是有可用的一个很好的权衡。
  • 看看你的国旗调整内存使用。 特别是在Java中的较新版本中,如果你没有很多长期的办学目标,考虑在堆撞了NEWGEN的大小。 NEWGEN(年轻)就是新的对象被分配。 对于一个网络服务器,对于请求创建一切都放在这里,如果这个空间太小,Java将花费额外的时间对象升级到寿命更长的记忆,在那里他们杀死更加昂贵。 (如果NEWGEN稍微太小,你会为它付出。)例如,在G1:
    • XX:G1NewSizePercent(默认为5;可能并不重要。)
    • XX:G1MaxNewSizePercent(默认为60,可能引发此。)
  • 考虑告知垃圾收集你不好吗具有较长的停顿。 这将导致更频繁的GC运行,允许系统,以保持它的约束休息。 在G1:
    • XX:MaxGCPauseMillis(默认为200)


Answer 4:

*“我个人靠归零变量作为未来适当的删除的占位符。例如,我采取实际删除(使空)数组本身之前废除数组中的所有元素的时间。”

这是不必要的。 在Java GC的工作方式是它发现没有提到他们,所以如果我有一个指向它的引用(=变量)一个一个对象x,GC将不会删除对象,因为有一个参考该对象:

a -> x

如果空比发生这种情况:

a -> null
     x

所以,现在的x不会有一个参考指向它,将被删除。 当您设置一个引用到不同的对象比X同样的事情发生。

所以,如果你有一个数组ARR该对象x,y和z和变量的引用,为它看起来像数组引用:

a -> arr -> x
         -> y
         -> z

如果空比发生这种情况:

a -> null
     arr -> x
         -> y
         -> z

所以GC发现改编为不具有参考设定,并删除它,它给你这样的结构:

a -> null
     x
     y
     z

现在,GC发现x,y和z和藏汉删除它们。 归零阵列中的每个参考不会做出更好的东西,它只会占用CPU时间和空间的代码(即表示,不会进一步损害比。GC将仍然能够执行的方式应)。



Answer 5:

从任何PROGRAMM(java或不)想释放内存的有效理由是为了让更多的可用内存在操作系统级别的其他节目评析。 如果我的Java应用程序是使用250MB我可能要迫使它下降到1MB,使249MB提供给其他应用程序。



Answer 6:

为了扩大经雅尼斯桑卓普洛斯和热舔(!对不起,我不能评论还)的答案和评论,你可以设置VM选项,如下面的例子:

-XX:+UseG1GC -XX:MinHeapFreeRatio=15 -XX:MaxHeapFreeRatio=30

在我的JDK 7,这将然后释放未使用的虚拟机内存如果堆的30%以上GC后成为自由当虚拟机处于闲置状态。 你可能需要调整这些参数。

当我没有看到它在下面的链接所强调的,注意一些垃圾收集器可能不遵守这些参数和默认的Java可挑的这些对你一个,你万一有一个以上的核心(因此上述UseG1GC说法)。

VM参数

更新:对于Java 1.8.0_73我已经看到了JVM偶尔释放出少量使用默认设置。 似乎只有这样做,如果〜堆的70%,未使用的,但..不知道这将是更积极的释放,如果操作系统是低的在物理内存。



Answer 7:

我对这个做了实验。

这是真的, System.gc(); 只是建议运行垃圾收集器。

但调用System.gc(); 设置的所有引用后null ,将改善性能和内存占用。



Answer 8:

如果你真的想分配和释放的内存块,你可以直接的ByteBuffers做到这一点。 甚至还有以释放内存不可移植的方式。

然而,由于已经提出,只是因为你有在C可用内存,并不意味着它一个好主意,不得不这样做。

如果你觉得你真的有一个免费的好的用例(),请包括它的问题,所以我们可以看到你rtying做什么,它很可能有一个更好的办法。



Answer 9:

完全由javacoffeebreak.com/faq/faq0012.html

低优先级的线程自动为用户负责垃圾收集的。 在空闲时间,线程可能会呼吁,并可以开始之前分配给Java中的对象的内存。 不过不要担心 - 它不会对你删除的对象!

当有一个对象的引用,它就会成为垃圾收集公平的游戏。 而不是调用一些程序(如免费的C ++),您只需分配给对象的所有引用为null,或指定一个新的类来参考。

例如:

 public static void main(String args[]) { // Instantiate a large memory using class MyLargeMemoryUsingClass myClass = new MyLargeMemoryUsingClass(8192); // Do some work for ( .............. ) { // Do some processing on myClass } // Clear reference to myClass myClass = null; // Continue processing, safe in the knowledge // that the garbage collector will reclaim myClass } 

如果你的代码是关于请求大量的内存,你可能想请求的垃圾收集器开始回收空间,而不是允许它作为一个低优先级的线程这样做。 要做到这一点,添加以下代码

 System.gc(); 

垃圾收集器将尝试回收可用空间,并且您的应用程序可以继续执行,以回收尽可能(内存碎片问题可以申请在某些平台上)尽可能多的内存。



Answer 10:

在我的情况,因为我的Java代码,就是要移植到在不久的将来(主要是C ++)其他语言,我至少要耍嘴皮子正确释放内存,以便它可以帮助以后的移植过程。

我个人靠归零变量作为未来适当的删除的占位符。 例如,我采取实际删除(使无效)数组本身之前废除的数组中的所有元素的时间。

但我的情况很特殊,我知道我是在性能开销执行此操作时。



Answer 11:

*“举个例子,说你会在宣布其增长的规模是非常大的一个方法的开始列表,但只需要通过之前的方法中途,你可以在此点设置列表引用为null以允许该方法完成(与参考超出范围无论如何)之前垃圾收集器可能回收此对象“。 *

这是正确的,但这种解决方案可能不具有普遍性。 同时设定了列表对象引用为null -will-使可用于垃圾回收内存,这仅仅是原始类型的List对象真实。 如果列表对象,而不是包含引用类型,设置列表对象= NULL不会取消引用-any-引用类型的包含-in-列表。 在这种情况下,设置列表对象= NULL将孤儿包含引用类型,其对象将进行垃圾回收,除非垃圾收集算法是足够聪明,确定对象已被孤立。



Answer 12:

g虽然Java提供了自动垃圾回收,有时你会想知道对象的大小以及使用编程是多少它离开。免费存储import java.lang;Runtime r=Runtime.getRuntime(); 获得使用的存储器中的值mem1=r.freeMemory(); 以释放内存调用r.gc(); 方法以及呼叫freeMemory()



Answer 13:

从JAVA的建议是分配给空

从https://docs.oracle.com/cd/E19159-01/819-3681/abebi/index.html

显式指派一个空值到不再需要的变量帮助垃圾收集器,以确定可以安全回收的内存部分。 虽然Java提供了内存管理,它不会阻止内存泄漏或使用过多的内存量。

一个应用程序可以通过不释放对象引用诱导内存泄漏。 这样做可以防止Java垃圾收集器从回收这些对象,并且在不断增加的存储器量的结果被使用。 明确抵消对变量的引用后,它们的使用允许垃圾回收器回收内存。

检测内存泄漏的方法之一是使用分析工具,并采取内存快照每次交易后。 在稳定状态下无泄漏的应用程序将显示垃圾收集后的稳定活性堆内存。



文章来源: How to free memory in Java?