内存泄漏 - 缺少垃圾收集器

发布于 2024-12-05 16:30:41 字数 330 浏览 1 评论 0原文

让我们考虑一个内存泄漏程序,其中一块堆内存没有被释放并且程序终止。如果这是(比如说)一个 Java 程序,那么内置的垃圾收集器将在程序退出之前自动释放该堆块。

但即使在 C++ 中,如果程序退出,内核也不会自动取消分配与进程关联的所有空间。同样在 Java 代码中,内核必须为进程的文本部分(代码)取消分配空间(即使堆栈和堆部分由垃圾收集器取消分配)。那么,使用垃圾收集器功能的总体优势是——只是增加了程序本身而不是内核释放堆所需的时间? (如果有任何这样的节省)

编辑:我的一个主要疑问是查看响应 - 当内存使用达到限制时,GC 会自动调用自身吗?因为,如果仅在程序终止之前调用 GC,那么它对于长程序没有用处。

Let us think of a memory leak program, wherein a block of heap memory is not freed and the program terminates. If this was (say) a Java Program, the in-built garbage collector would have automatically deallocated this heap block before the program exits.

But even in C++, if the program exits, wouldn't the Kernel automatically de-allocate all space associated with the process. Also in the Java code, the kernel would have to de-allocate the space for the text part (code) of the process (even if the stack and heap parts are deallocated by the garbage collector). So is the overall advantage of using a garbage collector feature - just the increased savings in time required to deallocate the heap by the program itself rather than the kernel? (if there is any such savings)

EDIT: A primary doubt of mine that has come about looking at the responses - will the GC invoke itself automatically when memory usage reaches a limit? Because, if a GC is only invoked just before the program terminates, it is not going to be useful for long programs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

染墨丶若流云 2024-12-12 16:30:41
  1. 这假设内核在您之后进行清理。并非所有操作系统都会自动处理动态分配的内存。 (但公平地说:大多数现代操作系统,至少在桌面上,
  2. 都是这样做的。)即使是回收所有内存的操作系统也只有在进程终止时才会这样做。大多数程序在其总运行时间中分配的内存远多于它们在任何给定时间点所需的内存(当运行足够长的时间时,对于许多数据处理应用程序来说,“长”可能是几秒钟)。
  3. 因此,许多进程(尤其是长时间运行的进程)在其生命周期中会产生越来越多的垃圾(不再使用的内存,也不会再次使用),并且没有希望在不终止的情况下摆脱它。 。您不想仅仅为了保持较低的内存使用量而终止并重新启动整个进程,对吗?
  4. 因为未使用的内存几乎永远不会被处理掉(有相当多的进程无限期地运行,有些可以运行几个小时),所以一段时间后你会遇到严重的内存短缺。您的浏览器会将您在此会话期间打开的所有图像、HTML 文档、JS 对象等保留在内存中,因为您无需每隔几分钟重新启动它。你说这是胡说八道,而且是浏览器中的一个严重问题?我的观点完全正确。
  5. 此外,大多数(也就是说,所有好的)GC 不会释放所有东西 - 当他们认为值得时,他们会不时运行,但当进程关闭后,内存中保留的所有内容都将被保留到较低级别(无论是自定义分配器还是操作系统)以进行释放。这也是为什么终结器不能保证运行的原因——在不进行多次分配的短期运行程序中,GC 可能永远不会运行。

所以不,GC 并不是为了节省时间。它可以节省大量内存,防止长时间运行的分配密集型程序占用所有可用内存,并最终导致每个人都因内存不足错误而死亡。

  1. That assumes that the kernel cleans up after you. Not all OSs take care of dynamically-allocated memory automatically. (But to be fair: Most modern ones, at least on the desktop, do.)
  2. Even the OSs that reclaim all memory only do so when the process terminates. Most programs allocate far more memory over their total runtime than they need at any given point in time (when run long enough, where "long" can be a few seconds for many data-crunching applications).
  3. Because of that, many - especially long-running - processes would create more and more garbage (memory that isn't used any more, and won't be used ever again) over their lifetime without any hope of getting rid of it without terminating. You don't want to kill and restart the whole process just to keep memory usage low, do you?
  4. Because unused memory is almost never (there are quite a few processes that run indefinitely and some that can run for hours) disposed of, you get serious memory shortage after a while. Your browser keeps all images, HTML documents, JS objects, etc. you opened during this session in memory because you won't bother to restart it every few minutes. That's bullshit and a serious problem in the browser, you say? My point exactly.
  5. Moreover, most (that is to say, all good ones) GCs don't deallocate everything - they run from time to time when they think it's worth it, but when the process shuts down, everything that remains in memory is left to a lower level (be it a custom allocator or the OS) to be freed. This is also why finalizers aren't guaranteed to run - in a short-running program that doesn't make many allocations, the GC may never run.

So no, GC isn't about saving time. It's about saving tons of memory, preventing long-running allocation-intense programs from hogging all available memory and eventually making everyone die from out of memory errors.

盗心人 2024-12-12 16:30:41

假设程序分配了一些资源,在运行时一直使用它,但在退出之前没有正确释放它。当该程序退出时,内核会释放所有程序资源 - 这是可以的。

现在考虑这样的情况:某个函数在每次调用时都会产生内存泄漏,并且该函数每秒被调用 100 次。几分钟或几小时后,该程序因没有可用内存而崩溃。

糟糕的是,造成类型 1 内存和资源泄漏的程序员通常会造成类型 2 泄漏,从而产生肮脏且不稳定的代码。专业程序员编写完美的代码,0资源和内存泄漏。如果垃圾收集器可用 - 就可以了。如果没有 - 自己管理资源。

顺便说一句,垃圾收集器仍然有可能造成泄漏 - 就像众所周知的 .NET 事件源-消费者泄漏一样。所以,垃圾收集器非常有用,节省了开发人员大量的时间,但无论如何开发人员必须小心管理程序资源。

Let's say that program allocates some resource, uses it all time it is running, but doesn't release it properly before exit. When this program exits, kernel deallocates all program resources - it is OK.

Now consider situation when some function creates memory leak on every call, and this function is called 100 times in a second. After few minutes or hours this program crashes because there is no free memory.

The bad thing is that programmer who makes memory and resource leaks of type 1, usually makes a leaks of type 2, producing dirty and unstable code. Professional programmer writes perfect code with 0 resource and memory leaks. If garbage collector is available - it is OK. If not - manage resources yourself.

BTW, it is still possible to make a leaks with garbage collector - like well-known .NET event source-consumer leak. So, garbage collector is very useful, saves a lot of developer time, but in any case developer must carefully manage program resources.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文