简体   繁体   English

如何在不调用System.gc()的情况下优化内存

[英]How to optimize memory without calling System.gc();

I am currently making an application that scan a folder and create Song for each file. 我目前正在制作一个扫描文件夹并为每个文件创建乐曲的应用程序。

[loop]
         if(!alreadyInLibrary(folder.getAbsolutePath())){
            Song s = new Song(folder.getAbsolutePath());
            this.addSong(s); // Add the song

            // Clear
            s = null;
            System.gc();
          }
[end loop]

If I call the GC my app consumme 150Mb of memory and 400Mb without. 如果我调用GC,我的应用程序将消耗150Mb的内存,而没有400Mb。 But calling GC each time is really slow. 但是每次调用GC确实很慢。 So, I wonder if there is another way to optimize memory. 因此,我想知道是否还有另一种优化内存的方法。

Thanks 谢谢

Generally you should never call System.gc() . 通常,您永远不应调用System.gc() GC is a sophisticated software component and it knows itself when to work and how much memory to free on each cycle. GC是一个复杂的软件组件,它知道自己何时工作以及每个周期可释放多少内存。

Moreover explicit invocation of System.gc() does not really call GC. 而且,显式调用System.gc()并不会真正调用GC。 It just politely asks GC to work. 它只是礼貌地要求GC工作。 It can start, but can postpone the request. 它可以启动,但是可以推迟请求。

This means that if you do not call GC the program runs until GC determines that it should work and then frees it. 这意味着如果您不调用GC,程序将运行直到GC确定它应该可以工作然后释放它。 So, the answer to your question is "just do not worry about the memory. Let GC to do its work when it thinks it is the time to work." 因此,您的问题的答案是“只是不必担心内存。让GC在认为该工作了的时候就开始工作”。

But. 但。 All this is relevant only if you do not have memory leaks that can happen for example if you store some not needed information in long-live collections. 仅当您没有可能发生的内存泄漏(例如,如果您将一些不需要的信息存储在长寿命的集合中)时,所有这一切才有意义。 Such entries should be cleaned programmatically. 此类条目应以编程方式清除。

The "right" way to work with GC in java is via various -X command line switches. 在Java中使用GC的“正确”方法是通过各种-X命令行开关。 The first step is just try to reduce the max heap limit, eg -Xmx180m . 第一步只是尝试减少最大堆限制,例如-Xmx180m Why 180? 为什么是180? Just because you said that when you invoke GC it occupies 150M. 仅仅因为您说过,当您调用GC时,它占用了150M。 Now try again. 现在再试一次。 If program runs well and performance is better now, try to reduce memory even more. 如果程序运行良好并且性能现在更好,请尝试进一步减少内存。 Take a look on other GC configuration parameters if it is needed. 如果需要,请查看其他GC配置参数。

Song s = new Song(folder.getAbsolutePath());
this.addSong(new Song(folder.getAbsolutePath())); // Add the song

// Clear
s = null;
System.gc();

This is asinine. 这是精氨酸。 The most memory efficient way to do this is simply: 最有效的内存方式是:

this.addSong(new Song(folder.getAbsolutePath())); // Add the song

You never used s. 您从未使用过。 You just created it, then set it to null, then GC'd it. 您刚刚创建了它,然后将其设置为null,然后对其进行了GC处理。 Instead just add it directly. 而是直接将其添加。 No need to do any premature optimization of this. 无需对此进行任何过早的优化。

There's no need to call the GC. 无需致电GC。 It will run when it needs to. 它会在需要时运行。 You generally never really need to call GC. 通常,您实际上根本不需要调用GC。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM