简体   繁体   English

强制JVM释放内存

[英]Force JVM to free memory

I improved my code to get a better result from the garbage collector. 我改进了我的代码,以便从垃圾收集器中获得更好的结果。

Now when i call System.gc() it does free all memory. 现在,当我调用System.gc()它释放所有内存。 But when I watch the memory usage without calling System.gc() the application does reserve and use more and more memory. 但是当我在不调用System.gc()的情况下观察内存使用情况时,应用程序会保留并使用越来越多的内存。

Does it mean my improvements are working and I got all my references right and I can ignore how the JVM does free memory by itself. 这是否意味着我的改进正在发挥作用,我的所有引用都是正确的,我可以忽略JVM如何自行释放内存。 Or are there another problems in my code that are the reasons why the JVM does reserve more memory without running the garbage collector. 或者我的代码中是否存在另一个问题,即JVM在不运行垃圾收集器的情况下保留更多内存的原因。

Depends which GC your JVM is using. 取决于您的JVM使用哪个GC。 If it is JDK9 then its probably G1 which is 'greedy' when it comes to memory consumption, so depending on the way in which you are checking memory utilized, it can appear as if it is taking up a lot of memory (where as this is reserving it and using/freeing dynamically/on demand. 如果它是JDK9那么它可能是G1,它在内存消耗方面是“贪婪”的,所以根据你检查内存使用的方式,它看起来好像占用了大量的内存(在这里保留它并动态/按需使用/释放。

You can use 您可以使用

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

to check memory consumption. 检查内存消耗。

And as for GC and memory consumption analysis check out following: High memory usage issues with G1 Garbage collector + https://www.javacodegeeks.com/2017/11/minimize-java-memory-usage-right-garbage-collector.html 至于GC和内存消耗分析,请查看以下内容: G1垃圾收集器的高内存使用问题 + https://www.javacodegeeks.com/2017/11/minimize-java-memory-usage-right-garbage-collector.html

Unused memory is wasted memory. 未使用的内存浪费了内存。

Why do you want to explicitly call System.gc() . 为什么要显式调用System.gc() IMHO, you should never call it and leave it up to the JVM to decide when to run GC. 恕我直言,你永远不应该调用它并将其留给JVM来决定何时运行GC。 (JVM can make better decisions than you if you are a novice. Call System.gc() only when you really know what you are doing.) It's generally a bad practice to call System.gc() . (如果你是新手JVM可以比你更好的决策。调用System.gc() ,只有当你真的知道自己在做什么。)这通常是一个不好的做法来调用System.gc()

System.gc() is just a request/hint to the JVM to run GC. System.gc()只是JVM运行GC的请求/提示。 It in no way means that for sure GC will run. 它绝不意味着GC肯定会运行。

You can have memory leaks in Java, but that's for sure not the thing to look at in your case because as you mentioned when you invoke System.gc() you can see some memory getting freed up. 您可以在Java中使用内存泄漏,但这肯定不是您在案例中要查看的内容,因为正如您在调用System.gc()时提到的那样,您可以看到一些内存被释放。 (So it is not the case that you are still holding the reference of unused objects which can prevent GC from cleaning up those objects.) (因此,您仍然不能保留未使用对象的引用,这可能会阻止GC清理这些对象。)

Why do you think it's a problem with your code? 为什么你认为这是你的代码的问题? It can be the case that no further memory is required or if memory is required, you already have plenty amount of it (and speaking in layman terms, GC don't frees up memory as there is still a lot for the program to run - so why should GC bother clearing the memory?). 可能的情况是不需要进一步的内存或者需要内存,你已经有足够的内存(并且以外行的话说,GC不会释放内存,因为程序运行还有很多 - 那么GC为什么要打扰内存?)

There is no way to force JVM to free up the memory, System.gc() is just a hint. 没有办法强制JVM释放内存, System.gc()只是一个提示。 It's up to GC to manage the memory (do note there are various types of memory eg heap, meta space, off-heap). 由GC来管理内存(注意有各种类型的内存,例如堆,元空间,堆外)。 Each GC algorithm has multiple configuration parameters that you can tweak but neither will give you an option to free up the memory on demand. 每个GC算法都有多个配置参数可供您调整,但两者都不会为您提供按需释放内存的选项。

JVM reserves memory on startup and requests additional memory from the OS until it reaches whatever limits are configured. JVM在启动时保留内存,并从操作系统请求额外的内存,直到达到配置的任何限制。 It does it in chunk increments, requesting MBs or more memory at a time, because requesting memory from the OS byte by byte would be very inefficient. 它以块增量执行,一次请求MB或更多内存,因为从字节逐字节地请求内存将是非常低效的。

There is of course a possibility that you have a memory leak, meaning that your program keeps allocating memory without ever freeing it. 当然有可能存在内存泄漏,这意味着您的程序在不释放内存的情况下不断分配内存。 (For example, in an ever-growing list or map.) You will need a memory profiler in order to make sure you are not suffering from such a situation. (例如,在不断增长的列表或地图中。)您将需要一个内存分析器,以确保您没有遭受这种情况。

Other than that, I would not worry if the virtual machine appears to keep allocating memory without freeing it. 除此之外,我不担心虚拟机是否会在不释放内存的情况下继续分配内存。 That's how modern VMs work, especially in "client" mode: for as long as there is plenty of free memory, they will not waste time with garbage collection. 这就是现代虚拟机的工作方式,特别是在“客户端”模式下:只要有足够的可用内存,它们就不会浪费时间进行垃圾收集。 If the limit of memory is approached, that's when the garbage collector will kick-in. 如果接近内存限制,那就是垃圾收集器启动的时间。 (The "client" vs. "server" mode is a JVM argument, you can experiment with it if you want, more info here: Real differences between "java -server" and "java -client"? ) (“客户端”与“服务器”模式是一个JVM参数,如果需要,可以试用它,更多信息: “java -server”和“java -client”之间的真正区别?

Other than that, what you can do is: 除此之外,你可以做的是:

a) make sure that your mechanism of performing a full GC is actually performing a full GC. a)确保执行完整GC的机制实际上是执行完整的GC。 The best mechanism that I know of (which is not guaranteed to work, but it seems to work as far as I can tell) is to allocate an object referenced only via a soft reference, and then keep calling GC until the soft reference becomes null. 我所知道的最好的机制(不能保证工作,但它似乎可以工作)就是分配一个仅通过软引用引用的对象,然后继续调用GC直到软引用变为null 。

b) on a debug run, (say, if assertions are enabled,) keep triggering a full GC on a separate thread every few seconds. b)在调试运行时(例如,如果启用了断言),每隔几秒就在一个单独的线程上继续触发一个完整的GC。 Then, if you look at the memory consumed by the VM, it should remain roughly constant. 然后,如果你查看VM消耗的内存,它应该保持大致不变。 If not, you have a memory leak. 如果没有,你有内存泄漏。

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

相关问题 jvm的可用内存空间越来越小 - jvm free memory space is getting smaller jvm崩溃..没有足够的免费记忆? (1.6) - jvm crash.. not enough free memory? (1.6) 如何估计JVM是否有足够的可用内存用于特定数据结构? - How to estimate if the JVM has enough free memory for a particular data structure? 对JVM进行性能分析:已提交,已使用,已释放内存 - Profiling JVM: Committed vs Used vs free Memory JVM 是否在不再需要时将可用内存返还给操作系统? - Does the JVM give back free memory to the OS when no longer needed? 强制JVM尽早收集垃圾并尽早减少系统内存 - Force the JVM to collect garbage early and reduce system memory used early java.nio.DirectByteBuffer 尝试在 GC 中释放内存时 JVM 崩溃 - JVM crash when java.nio.DirectByteBuffer trying to free memory in GC 为什么在我的测试程序之后 JVM 有更多的免费 memory? - Why does the JVM have more free memory after my test program? 有没有办法强制JVM使用swap,无论内存需求有多大? - Is there any way to force a JVM to use swap no matter how big the memory requirement is? 64位Windows上的32位JVM在启动时崩溃,使用-Xmx1300m和大量可用内存 - 32-bit JVM on 64-bit Windows crashes on launch with -Xmx1300m and plenty of free memory
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM