1

我正在编写一个生成并杀死 Chrome 浏览器的应用程序。虽然我以编程方式终止进程(与通过 Windows 任务管理器终止进程的效果相同),但有人建议这也可能导致内存泄漏 - 即来自与原始进程未正确关联的内核资源等元素.

在进程被杀死后,应用程序是否有可能泄漏内存或以其他方式拥有不可回收的内存?

4

4 回答 4

2

可能会发生,但当它发生时,它绝不是程序中的错误。它总是由 Windows 内核代码或某些内核驱动程序中的错误/错误引起的。此外,您甚至不太可能在 Windows 的标准安装中遇到此类行为。

于 2012-05-02T22:09:23.477 回答
1

一个程序可能会启动多个进程。杀死父进程本身并不能保证子进程会终止。这可能看起来像内存泄漏。就操作系统而言,所有分配的内存仍然与正在运行的进程相关联,只是您可能不希望所有这些进程仍在运行。

就 Chrome 而言,它确实产生了许多子进程。我认为它可以确保当父进程意外终止时它们会自行清理,但我不能确定。

于 2012-05-02T22:20:53.893 回答
1

直接在任务管理器中杀死进程可能会导致内存泄漏。有证据表明不断杀死“explorer.exe”会减慢整个操作系统的速度。

每个 Chrome 窗口都有一个 GUI 进程和每个活动选项卡的后台进程。后台进程负责获取页面内容、发送请求/发布数据,并且比 GUI 进程持有更少的内核对象句柄。任何编程框架都会有至少两种方法来关闭活动进程。例如,在 .NET 中,Process 类有以下两种方法:

  1. 关闭主窗口()
    • 向主窗口消息循环发送 WM_QUIT 消息以请求关闭进程。这使程序有机会重新调用其子窗口及其内核对象。
  2. 杀()
    • 强制终止进程,与在任务管理器中终止进程相同。这是关闭后台进程的唯一方法。但是当这适用于 GUI 进程时,这不会触发所有 GUI/内核事件来释放资源。内核对象包括 GDI 对象、文件/打印机句柄、数据库/网络连接上下文等。释放这些资源需要一些时间,同时跟踪整个内存链表/映射以释放内核对象的资源。甚至 .NET/java 都有它的垃圾收集器来确定释放“托管”内存,内核对象的非托管资源并不总是被覆盖。

以下是 .NET C# 中的测试应用程序。我们可以使用 Visual Studio 附加组件将 CloseMainWindow() 与 Kill() 进行比较:Memory Profiler。在几乎所有情况下,Kill() 速度更快,但通过检查实时内存图中的“根引用”和“实例引用”释放的内存更少。

private Process _chromeProcess = new Process();

private void bntCreate_Click(object sender, EventArgs e)
{
    string chromePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        @"Google\Chrome\Application\chrome.exe");

    _chromeProcess.StartInfo = new ProcessStartInfo(chromePath, @"-app=http://localhost:(a local Web site)");
    _chromeProcess.Start();
}

private void btnKill_Click(object sender, EventArgs e)
{
    _chromeProcess.Kill();
    _chromeProcess.WaitForExit();
    _chromeProcess.Close();
}

private void btnClose_Click(object sender, EventArgs e)
{
    _chromeProcess.CloseMainWindow();
    _chromeProcess.WaitForExit();
    _chromeProcess.Close();
}
于 2012-05-05T22:49:49.600 回答
0

如果一个程序在剪贴板上放置了大量内存,它可能看起来像内存泄漏,但剪贴板仍然负责内存,并在其他东西复制新内容时释放它。

这是我能想到的唯一一种内存超过程序生命周期的情况。

于 2012-05-02T22:14:03.767 回答