आपने उल्लेख किया है, यह आंशिक रूप से आरक्षित पृष्ठों की एक श्रृंखला जारी करने के लिए संभव हो सकता है प्रकट नहीं होता है क्योंकि VirtualFree()
documentation कहता है:
तो dwFreeType पैरामीटर MEM_RELEASE है, [lpAddress] चाहिए पेजों का क्षेत्र आरक्षित था जब VirtualAlloc समारोह द्वारा लौटा आधार पता हो।
के साथ-साथ:
dwFreeType पैरामीटर MEM_RELEASE है, तो [dwSize] होना चाहिए 0 (शून्य)।
VirtualFree()
स्वयं कर्नेल फ़ंक्शन NtFreeVirtualMemory()
का पतला आवरण है। Its documentation page (ZwFreeVirtualMemory()
के समान) इस शब्द भी है।
एक संभावित काम-चारों ओर एक छोटे, बड़े आरक्षण को कई छोटे लोगों के साथ विभाजित करना है। उदाहरण के लिए, मान लीजिए कि आप आम तौर पर एक समय में वर्चुअल एड्रेस स्पेस के 8 एमआईबी आरक्षित करते हैं। आप इसके बजाय तीसरे दो संगत 256 केबी आरक्षण में सीमा को आरक्षित करने का प्रयास कर सकते हैं।
#define NOMINMAX
#include <windows.h>
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define RESERVATION_SIZE (256*1024)
typedef struct st_first_reservation {
size_t reservation_size;
uint32_t rfield;
char premaining[0];
} st_first_reservation;
int main()
{
SYSTEM_INFO sys_info = { 0 };
GetSystemInfo(&sys_info);
assert((RESERVATION_SIZE % sys_info.dwPageSize) == 0);
void *vp = VirtualAlloc(NULL, 32*RESERVATION_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (VirtualFree(vp, 0, MEM_RELEASE) == 0) {
fprintf(stderr, "Error: VirtualFree() failed.\n");
return EXIT_FAILURE;
}
st_first_reservation *pfirst_reservation = (st_first_reservation *) VirtualAlloc(vp, RESERVATION_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (pfirst_reservation == NULL) {
pfirst_reservation = (st_first_reservation *) VirtualAlloc(NULL, RESERVATION_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (pfirst_reservation == NULL) {
fprintf(stderr, "Error: VirtualAlloc() failed.\n");
return EXIT_FAILURE;
}
}
fprintf(stderr, "pfirst_reservation = 0x%p\n", (void *) pfirst_reservation);
pfirst_reservation->reservation_size = RESERVATION_SIZE;
pfirst_reservation->rfield = 1LU;
char *p = (char *) pfirst_reservation;
unsigned i = 1;
for (; i < 32; ++i) {
vp = VirtualAlloc(p += RESERVATION_SIZE, RESERVATION_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (vp != NULL) {
assert(((void *) vp) == p);
pfirst_reservation->rfield |= 1LU << i;
fprintf(stderr, "Obtained reservation #%u\n", i + 1);
} else {
fprintf(stderr, "Failed to obtain reservation #%u\n", i + 1);
}
}
fprintf(stderr, "pfirst_reservation->rfield = 0x%08x\n", pfirst_reservation->rfield);
return EXIT_SUCCESS;
}
नमूना उत्पादन: पहले 256 किबा आरक्षण एक 32-बिट अहस्ताक्षरित सा क्षेत्र है, जहां मैंवें बिट अगर मैंवें 256 किबा आरक्षण प्राप्त हुई थी सेट किया गया है शामिल हैं:
pfirst_reservation = 0x009A0000
Obtained reservation #2
Obtained reservation #3
Obtained reservation #4
Obtained reservation #5
Obtained reservation #6
Obtained reservation #7
Obtained reservation #8
Obtained reservation #9
Obtained reservation #10
Obtained reservation #11
Obtained reservation #12
Obtained reservation #13
Obtained reservation #14
Obtained reservation #15
Obtained reservation #16
Obtained reservation #17
Obtained reservation #18
Obtained reservation #19
Obtained reservation #20
Obtained reservation #21
Obtained reservation #22
Obtained reservation #23
Obtained reservation #24
Obtained reservation #25
Obtained reservation #26
Obtained reservation #27
Obtained reservation #28
Obtained reservation #29
Obtained reservation #30
Obtained reservation #31
Obtained reservation #32
pfirst_reservation->rfield = 0xffffffff
संपादित करें: मैं ने पाया है कि यह बेहतर है "पूर्व आरक्षित" बत्तीस 256 किबा सभी को एक बार पर्वतमाला, नि: शुल्क है, और वें के लिए जितना आप कर सकते हैं उतना पुनः आरक्षित करने की कोशिश करें।
मैंने ऊपर कोड और नमूना आउटपुट अपडेट किया।
एक बहुप्रचारित वातावरण में, कोड पहले आरक्षण के "स्थान कहीं भी" आवंटन में वापस आ सकता है। शायद RESERVATION_SIZE
बाइट्स को 32*RESERVATION_SIZE
बाइट्स की आरक्षित-मुक्त-मुक्त सीमा पर पांच या उससे अधिक बार आरक्षित करने का प्रयास करना एक अच्छा विचार है, अंततः "कहीं भी स्थान" आवंटन पर वापस आना।
वर्चुअल मेमोरी का पूरा बिंदु इस सामान को दूर करना है और कर्नेल को स्मृति प्लेसमेंट से निपटने देना है। –
क्या आपके एप्लिकेशन को वर्चुअल मेमोरी के पेज जारी करने की आवश्यकता है; क्या आप आभासी पता स्थान से बाहर हो रहे हैं? –
@DanielTrebbien: स्थिति निम्नानुसार है .. मुझे एक नया क्षेत्र चाहिए, इसलिए मैं इसे वर्चुअलअलोक के साथ आवंटित करने का प्रयास करता हूं। हालांकि, वर्चुअलअलोक एक आउट-ऑफ-मेमोरी फेंकता है। उसी समय, कुछ मेटाडाटा के कारण मैं खुद को रख रहा हूं, मुझे पता है कि कुछ क्षेत्र केवल आधा भरा है। अब मैं उन क्षेत्रों को सस्ता रूप से घटाना या फिर से शुरू करना चाहता हूं जब तक कि मुझे स्मृति न हो। – cib