当前位置: 首页 > 知识库问答 >
问题:

是否有可能另一个程序重用已分配的空闲内存,然后由已运行的其他程序释放?

庾兴发
2023-03-14

假设我有一个Linux(64位,内核2.6,glibc 2.4)操作系统,运行在一台8Gb RAM的机器上。所有引用的程序都是C实现。

程序A启动了,假设它分配(并在其中写入信息)5 Gb的内存(执行malloc)。在此之后,它释放了所有预分配的内存。这意味着我们有一个进程,曾经在内存中加载了5 Gb的内存,现在正在以非常低的内存使用率运行。

当程序A仍在运行并且没有使用内存时,我启动同一程序的另一个实例(我称之为程序B),尝试分配5Gb的内存。

我观察到的是,程序B无法保留所有内存,操作系统开始交换,尽管理论上它应该有足够的可用RAM。得出的结论是,程序A保留了5 Gb的可用RAM以供将来使用,并且不能用于任何其他程序。

从操作系统或任何其他需要分配大量内存的程序的角度来看,程序释放的内存会发生什么?有没有办法在不停止程序A的情况下强制操作系统释放这些内存?

抱歉,过于简单化了。

提前感谢!

PS:使用的代码类似于此:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

int main(int argc, char** argv) {
    int max = -1;
    int mb,x = 0;
    char* buffer[1000];

    if(argc > 1)
        max = atoi(argv[1]);

    while((buffer[mb]=malloc(50*1024*1024)) != NULL && mb != max) {
        memset(buffer[mb], 0, 50*1024*1024);
        mb++;
        printf("Allocated %d Mem Blocks, totalling %d\n", mb,mb*50);
        sleep(1);
        if((mb%15)==0)
    {
        for(x=0;x<5;x++)
        {   
        mb--;
                free(buffer[mb]);
            printf("Allocated %d Mem Blocks, totalling %d\n", mb,mb*50);
            sleep(2);
        }
    }
    }

    return 0;
}

共有2个答案

萧浩漫
2023-03-14

在linux中,我们使用此命令释放内存和脏缓存。。

同步;回声3

希望这将有助于释放未使用的内存。

融烨磊
2023-03-14

请参阅malloc实现是否会将可用的ed内存返回到系统?以获取解释。如果您确实对二进制文件进行了strace,您将看到内存是使用mmap()分配的,但没有释放,即使您调用free()。

所需的是free()将内存返回给进程,而不是操作系统。使用glibc,可以调用malloc\u trim(),但这仅适用于sbrk()分配的内存,如果使用mmap()满足分配,则不适用

 类似资料:
  • 我对高级Java没有经验,所以请原谅我。 我对Java实现可以称为“自主”的特性的能力很好奇。假设我们有两个Java程序在运行。一个程序确定另一个程序占用内存,因此杀死该程序和/或为JVM分配更多内存。

  • 问题内容: 如果我有另一个正在运行的apache / web-server实例,我用所有这些命令痛苦地分析了昨天的全部内容 我没有在端口8080上运行的Apache或任何其他服务器的另一个实例。 但是,XAMPP给了我这个: 我该怎么办? 我也将httpd.conf编辑为LISTEN到端口9876,并且仍然相同。 问题答案: 如果: 然后,也许有一个锁定文件位于启动要检查的地方?这些通常在/ va

  • 如果我有另一个apache/web服务器实例在运行,我已经痛苦地分析了昨天的所有内容,包括所有这些命令 我没有在端口8080上运行的Apache或任何其他服务器的另一个实例。 然而,XAMPP给了我这样的信息: 我该怎么办? 我还编辑了httpd.conf监听端口9876,仍然是一样的。

  • 问题内容: 我需要从自己的Java程序中运行其他几个程序,基本上我需要运行这些命令行语句。 和 并且我需要在自己的程序中使用从这些程序写入控制台的文本输出。我已经尝试过使用svn运行Runtime.getRuntime()。exec(),但是它似乎没有做任何事情,因为它没有生成svn.log文件。同样,两个程序都需要在不同的地方调用,svn行需要从一个文件夹内调用,而java行需要从另一文件夹内调

  • 问题内容: 我最近开始分析我使用VisualVM编写的osgi Java应用程序。我注意到的一件事是,当应用程序开始(通过JMS)向客户端发送数据时,已加载类的数量开始以稳定的速度增加。但是,堆大小和PermGen大小保持不变。即使停止发送数据,类的数量也永远不会减少。这是内存泄漏吗?我认为是这样,因为已加载的类必须存储在某个位置,但是即使我将应用程序运行了几个小时,堆和permgen也不会增加。

  • 问题 使用CDI,我希望生成bean。 此外,我希望为注入点提供配置注释,例如: 我不想为的每个不同可能性编写一个单独的生产者。 方法 通常的方法是创建一个生产者并处理注入点注释: 因此,bean不能再被应用程序限定范围,因为每个注入点可能不同(producer的参数injectionpoint不适用于注释的生产者)。 所以这个解决方案不起作用。 问题 我需要具有相同值的注入点获得相同bean实例