bss和数据的最大大小

时间:2012-08-25 22:21:27

标签: c linux

我想在编译时声明我的C程序中的所有变量,例如:

char cache[CACHE_SIZE];
char udp_ring[MAX_UDP_PACKET_SIZE*MAX_REQUESTS];
int  num_packets;
char error_codes[NUM_ERRORS][MAX_ERROR_STRING]= {
    {"Unknown user\n"},
    {"Wrong password\n"},
    ....
};

问题是,当C程序进入BSS或DATA段时,变量的大小是否有限制? 例如,如果我声明8GB RAM的CACHE_SIZE,它会工作吗? 32位或64位有什么区别吗?我计划在Linux上运行程序,我的RLIMIT_DATA配置没有限制。

2 个答案:

答案 0 :(得分:4)

您将能够管理内核允许进程处理的虚拟内存:它将取决于体系结构。

例如,在x86架构上(没有x86-64长模式),Linux默认情况下将进程看到的虚拟内存分为3GB进程和内核1GB(即使PAE已启用):您的进程将无法处理超过3GB的虚拟内存(包括文本部分,数据,bss,堆,堆栈,共享对象等)。

如果静态分配所有缓冲区并且内核无法将其放入进程虚拟地址空间,则它将在启动时被终止:使用8GB缓冲区将主要导致32位体系结构中的此行为。< / p>

如果你不想依赖glibc的内存管理功能(malloc,...),你可以推出自己的内存管理库并强制你的进程使用LD_PRELOAD诀窍,这样你就可以定义符合你自己要求的malloc/calloc/realloc/free(使用sbrk())实现。

答案 1 :(得分:2)

如果您不想与glibc关联,您应该找到一些奇怪的方法来syscalls(在syscalls(2)手册页中列出)。任何应用程序都必须执行一些系统调用(例如open(2)read(2)write(2) ...)。 Glibc还用于为系统调用提供C接口。 assembly howto解释了如何在没有libc的情况下调用syscalls,直接使用一些汇编代码(例如通过C asm指令)。另请参见过时的_syscall(2)手册页。另请参阅VDSO

您可以使用mmap(2)munmap(2)系统调用来更改地址空间。这是分配和释放内存的基本操作。 Glibc使用它们来实现mallocfree

将所有变量声明为全局或静态,无论是初始化(.data段)还是已清除(.bss段)都有一个明显的缺点:您无法使用动态内存资源。并且拥有大量初始化数据会产生巨大的成本:您的ELF可执行文件会非常庞大​​。

但你真的应该解释为什么你要避免Glibc。在用C编码时很难避免它。你可以使用更轻的替代品,如dietlibc