主存(內存)一般被視為非可搶佔資源,即進程已經分配內存後,操作系統不會輕易將其從該進程中搶佔。然而在一些情況下,主存也可以被視為可搶佔資源。
一、 內存分配
在大多數情況下,內存是由操作系統在進程啟動時分配的。操作系統負責為進程中的每個線程分配一些私有內存,進程中的所有線程共享一些公共內存。
例如,在Linux中,可以使用malloc()函數為變量或數組分配內存。該函數從進程的堆中分配內存,並返回一個指向所分配內存的指針。操作系統將返回的內存區域映射到該進程的地址空間中,這樣進程就可以訪問該內存區域。
然而,在某些情況下,操作系統可能會搶佔部分內存區域並將其分配給其他進程。例如,當系統的物理內存不足時,操作系統可能會利用虛擬內存技術將進程的部分內存映射到磁盤上,在需要時再將其讀入內存中。當系統需要更多內存時,操作系統可能會將進程佔用的部分內存寫回磁盤並將其搶佔。
int main()
{
// 分配10個整數的數組
int* nums = (int*)malloc(10 * sizeof(int));
if (nums == NULL)
{
printf("內存分配失敗!\n");
return -1;
}
for (int i = 0; i < 10; i++)
{
nums[i] = i;
}
// 釋放內存
free(nums);
return 0;
}
二、 內存泄漏
內存泄漏是指應用程序分配內存後,未能釋放該內存,最終導致系統中的可用內存不足。內存泄漏可能導致系統崩潰或嚴重性能下降。
例如,在下面的代碼中,如果忘記使用free()函數釋放nums變量,則可能導致內存泄漏。
int main()
{
// 分配10個整數的數組
int* nums = (int*)malloc(10 * sizeof(int));
if (nums == NULL)
{
printf("內存分配失敗!\n");
return -1;
}
// 忘記釋放內存
return 0;
}
三、虛擬內存
虛擬內存是一種將進程內存映射到磁盤空間的技術。當進程需要訪問某個內存頁時,操作系統將從磁盤中讀取該頁到物理內存中。因此,虛擬內存為進程提供了一個比物理內存更大的地址空間。
當系統物理內存不足時,操作系統可能會將某些頁寫回磁盤並將其搶佔。因此,虛擬內存是一種可搶佔資源。
下面的代碼演示了如何使用虛擬內存技術,將進程的內存映射到磁盤上:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
int main()
{
int fd, i;
char* ptr;
// 打開文件,如果不存在則創建它
fd = open("test.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (fd == -1)
{
printf("文件打開失敗!\n");
return -1;
}
// 調整文件大小為4KB
if (ftruncate(fd, 4096) == -1)
{
printf("文件調整大小失敗!\n");
close(fd);
return -1;
}
// 將文件映射到內存中
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED)
{
printf("內存映射失敗!\n");
close(fd);
return -1;
}
// 寫入數據
for (i = 0; i < 4096; i++)
{
ptr[i] = i % 256;
}
// 解除內存映射
if (munmap(ptr, 4096) == -1)
{
printf("內存解除映射失敗!\n");
close(fd);
return -1;
}
// 關閉文件
close(fd);
return 0;
}
四、可交換內存
可交換內存是一種僅在內存不足時才會被搶佔的內存。例如,在Linux中,可交換內存可以通過將頁面從物理內存中交換到交換分區或磁盤上來實現。
下面的代碼演示了如何創建一個使用可交換內存的進程:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int i;
char* ptr;
// 使用可交換內存分配10MB內存
ptr = (char*)malloc(1024 * 1024 * 10);
if (ptr == NULL)
{
printf("內存分配失敗!\n");
return -1;
}
// 寫入數據
for (i = 0; i < 1024 * 1024 * 10; i++)
{
ptr[i] = i % 256;
}
// 休眠10秒,等待操作系統將頁面寫回磁盤
sleep(10);
// 釋放內存
free(ptr);
return 0;
}
原創文章,作者:AYIMH,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/375357.html