当前位置: 首页 > news >正文

网站建设东莞长安镇燃灯seo

网站建设东莞长安镇,燃灯seo,安徽全过程网站搭建案例,wordpress 短代码使用在程序的应用开发时候,面对内存密集型操作时,需要大量内存,可能需要远超物理内存空间的内存,该怎么做呢? 假设现在的机器是64位的windows,其用户的虚地址空间是0x000’000000000到0x7FFF’FFFFFFFF&#xf…

在程序的应用开发时候,面对内存密集型操作时,需要大量内存,可能需要远超物理内存空间的内存,该怎么做呢?
假设现在的机器是64位的windows,其用户的虚地址空间是0x000’000000000到0x7FFF’FFFFFFFF,约128 TB。

可以考虑提前申请空间到数据段

#include <iostream>
constexpr size_t K_ = 1024;
constexpr size_t KB_ = K_;
constexpr size_t MB_ = K_ * KB_;
constexpr size_t GB_ = K_ * MB_;
constexpr size_t TB_ = K_ * GB_;
uint8_t gBuff[10 * GB_];
int main()
{return 0;
}

这样可以得到一个编译错误

错误	C2148	数组的总大小不得超过 0x7fffffff 字节

可以考虑使用malloc动态申请内存
malloc会申请到一块连续的内存,如果失败,会返回空指针

#include "stdafx.h"
#include <iostream>constexpr size_t K_ = 1024;
constexpr size_t KB_ = K_;
constexpr size_t MB_ = K_ * KB_;
constexpr size_t GB_ = K_ * MB_;
constexpr size_t TB_ = K_ * GB_;int main()
{void* ptr = malloc(48 * GB_);if (!ptr) {std::cerr << strerror(errno) << std::endl;exit(EXIT_FAILURE);}return 0;
}

这样的话就只能退一步,分批申请小块内存,一直到申请内存的总量是达到预期。

#include "stdafx.h"
#include <iostream>constexpr size_t K_ = 1024;
constexpr size_t KB_ = K_;
constexpr size_t MB_ = K_ * KB_;
constexpr size_t GB_ = K_ * MB_;
constexpr size_t TB_ = K_ * GB_;void* MyMalloc(const size_t expect, size_t& actual)
{actual = expect;void *ptr = nullptr;while (actual && !(ptr = malloc(actual))){actual = actual>>1;}return ptr;
}int main()
{size_t expect = 48 * GB_;constexpr int len = 0xffff;void* buff[len];int i = 0;for (i = 0; i < len && expect; ++i){size_t actual;buff[i] = MyMalloc(expect, actual);if (buff[i] && actual){expect -= actual;std::cout << "malloced (" << actual << ") = " << buff[i] << std::endl;}else {break;}}if (expect) {std::cerr << "malloc big memory fail!" << std::endl;}for (i = 0; i < len && buff[i]; ++i){free(buff[i]);buff[i] = nullptr;}return 0;
}

可能会得到一个崩溃
在这里插入图片描述
windows上的malloc可能是使用HeapAlloc或VirtualAlloc实现的,内存不够用的时候发生崩溃。

需要借助VirualAlloc
具体查看 Windows虚拟内存函数

#include <iostream>
#include <windows.h>constexpr size_t K_ = 1024;
constexpr size_t KB_ = K_;
constexpr size_t MB_ = K_ * KB_;
constexpr size_t GB_ = K_ * MB_;
constexpr size_t TB_ = K_ * GB_;void* MyAlloc(const size_t expect, size_t& actual)
{actual = expect;void *ptr = nullptr;while (actual && !(ptr = VirtualAlloc(nullptr, actual, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))){actual = actual >> 1;}return ptr;
}bool MyFree(void* ptr)
{return (TRUE == VirtualFree(ptr, 0, MEM_RELEASE));
}int main()
{size_t expect = 48 * GB_;constexpr int len = 0xffff;void* buff[len];int i = 0;for (i = 0; i < len && expect; ++i){size_t actual;buff[i] = MyAlloc(expect, actual);if (buff[i] && actual){expect -= actual;std::cout << "myalloced (" << actual << ") = " << buff[i] << std::endl;}else {break;}}if (expect) {std::cerr << "alloc big memory fail!" << std::endl;}else {std::cout << "alloced success" << std::endl;}for (i = 0; i < len && buff[i]; ++i){MyFree(buff[i]);buff[i] = nullptr;}return 0;
}

虚拟内存可能在不使用的时候暂存到硬盘交换区中去,可以使用MEM_RESET与MEM_RESET_UNDO来操作。

#include "stdafx.h"
#include <iostream>
#include <cassert>
#include <windows.h>constexpr size_t K_ = 1024;
constexpr size_t KB_ = K_;
constexpr size_t MB_ = K_ * KB_;
constexpr size_t GB_ = K_ * MB_;
constexpr size_t TB_ = K_ * GB_;constexpr size_t len = 0xffff;
uint8_t* buff[len];size_t MyCommit(void* const basePtr, const size_t expect)
{size_t actual = expect;while (actual && !VirtualAlloc(basePtr, actual, MEM_COMMIT, PAGE_READWRITE)){actual >>= 1;}if (actual) {MEMORY_BASIC_INFORMATION memInfo;VirtualQuery(basePtr, &memInfo, sizeof(memInfo));if (memInfo.BaseAddress == basePtr && memInfo.State == MEM_COMMIT) {actual = memInfo.RegionSize;}else {actual = 0;}}return actual;
}int main()
{MEMORY_BASIC_INFORMATION memInfo;constexpr size_t expect = 64 * GB_;// 无法直接申请到超大块内存,需要先预订内存void* ptr = VirtualAlloc(nullptr, expect, MEM_RESERVE, PAGE_NOACCESS);VirtualQuery(ptr, &memInfo, sizeof(memInfo));printf("基地址: %p, 状态: %x, 大小: %zu 字节\n", memInfo.BaseAddress, memInfo.State, memInfo.RegionSize);// 然后申请内存const size_t actual = MyCommit(ptr, expect);assert(actual);VirtualQuery(ptr, &memInfo, sizeof(memInfo));printf("基地址: %p, 状态: %x, 大小: %zu 字节\n", memInfo.BaseAddress, memInfo.State, memInfo.RegionSize);// 在申请到内存内写入数据for (int i = 0; i < 10; ++i) {((uint8_t*)ptr)[i] = i + 1;}// 现在对刚刚的内存不感兴趣了,可以暂存的交换区VirtualAlloc(ptr, 0, MEM_RESET, PAGE_NOACCESS);VirtualQuery(ptr, &memInfo, sizeof(memInfo));printf("基地址: %p, 状态: %x, 大小: %zu 字节\n", memInfo.BaseAddress, memInfo.State, memInfo.RegionSize);// 去申请下一块内存size_t next_expect = expect - actual;void* next_ptr = (void*)((size_t)ptr + actual);const size_t next_actual = MyCommit(next_ptr, next_expect);VirtualQuery(next_ptr, &memInfo, sizeof(memInfo));printf("基地址: %p, 状态: %x, 大小: %zu 字节\n", memInfo.BaseAddress, memInfo.State, memInfo.RegionSize);assert(next_actual);for (int i = 0; i < 10; ++i) {((uint8_t*)next_ptr)[i] = i + 1;}// 把申请到的next_ptr 暂存到交换区VirtualAlloc(next_ptr, 0, MEM_RESET, PAGE_NOACCESS);VirtualQuery(next_ptr, &memInfo, sizeof(memInfo));printf("基地址: %p, 状态: %x, 大小: %zu 字节\n", memInfo.BaseAddress, memInfo.State, memInfo.RegionSize);// 把ptr处的内存从交换区中取出VirtualAlloc(ptr, actual, MEM_RESET_UNDO, PAGE_READWRITE);VirtualQuery(ptr, &memInfo, sizeof(memInfo));printf("基地址: %p, 状态: %x, 大小: %zu 字节\n", memInfo.BaseAddress, memInfo.State, memInfo.RegionSize);// 读取数据for (int i = 0; i < 10; ++i) {std::cout << int(((uint8_t*)ptr)[i]) << std::endl;}VirtualFree(ptr, 0, MEM_RELEASE);VirtualQuery(ptr, &memInfo, sizeof(memInfo));printf("基地址: %p, 状态: %x, 大小: %zu 字节\n", memInfo.BaseAddress, memInfo.State, memInfo.RegionSize);return EXIT_SUCCESS;
}

如果是32位的应用程序像突破4GB的寻址限制,需要使用到地址窗口化扩展, 简称AWE。
微软官方示例


#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <tchar.h>constexpr size_t MEMORY_REQUESTED = 1024 * 1024;BOOL
LoggedSetLockPagesPrivilege(HANDLE hProcess,BOOL bEnable);size_t GetPageSize() {static size_t page_size = 0;if (page_size == 0) {SYSTEM_INFO sSysInfo;GetSystemInfo(&sSysInfo);page_size = sSysInfo.dwPageSize;}return page_size;
}void  main()
{BOOL bResult;                   // generic Boolean valueULONG_PTR NumberOfPages;        // number of pages to requestULONG_PTR NumberOfPagesInitial; // initial number of pages requestedULONG_PTR *aPFNs;               // page info; holds opaque dataPVOID lpMemReserved;            // AWE windowint PFNArraySize;               // memory to request for PFN array_tprintf(_T("This computer has page size %d.\n"), GetPageSize());// Calculate the number of pages of memory to request.NumberOfPages = MEMORY_REQUESTED / GetPageSize();_tprintf(_T("Requesting %d pages of memory.\n"), NumberOfPages);// Calculate the size of the user PFN array.PFNArraySize = NumberOfPages * sizeof(ULONG_PTR);_tprintf(_T("Requesting a PFN array of %d bytes.\n"), PFNArraySize);aPFNs = (ULONG_PTR *)HeapAlloc(GetProcessHeap(), 0, PFNArraySize);if (aPFNs == NULL){_tprintf(_T("Failed to allocate on heap.\n"));return;}// Enable the privilege.if (!LoggedSetLockPagesPrivilege(GetCurrentProcess(), TRUE)){return;}// Allocate the physical memory.NumberOfPagesInitial = NumberOfPages;bResult = AllocateUserPhysicalPages(GetCurrentProcess(),&NumberOfPages,aPFNs);if (bResult != TRUE){_tprintf(_T("Cannot allocate physical pages (%u)\n"), GetLastError());return;}if (NumberOfPagesInitial != NumberOfPages){_tprintf(_T("Allocated only %p pages.\n"), NumberOfPages);return;}// Reserve the virtual memory.lpMemReserved = VirtualAlloc(NULL,MEMORY_REQUESTED,MEM_RESERVE | MEM_PHYSICAL,PAGE_READWRITE);if (lpMemReserved == NULL){_tprintf(_T("Cannot reserve memory.\n"));return;}// Map the physical memory into the window.bResult = MapUserPhysicalPages(lpMemReserved,NumberOfPages - 3,&aPFNs[3]);if (bResult != TRUE){_tprintf(_T("MapUserPhysicalPages failed (%u)\n"), GetLastError());return;}// unmapbResult = MapUserPhysicalPages(lpMemReserved,NumberOfPages - 3,NULL);if (bResult != TRUE){_tprintf(_T("MapUserPhysicalPages failed (%u)\n"), GetLastError());return;}// Free the physical pages.bResult = FreeUserPhysicalPages(GetCurrentProcess(),&NumberOfPages,aPFNs);if (bResult != TRUE){_tprintf(_T("Cannot free physical pages, error %u.\n"), GetLastError());return;}// Free virtual memory.bResult = VirtualFree(lpMemReserved,0,MEM_RELEASE);// Release the aPFNs array.bResult = HeapFree(GetProcessHeap(), 0, aPFNs);if (bResult != TRUE){_tprintf(_T("Call to HeapFree has failed (%u)\n"), GetLastError());}}/*****************************************************************
LoggedSetLockPagesPrivilege: a function to obtain or
release the privilege of locking physical pages.Inputs:HANDLE hProcess: Handle for the process for which the
privilege is neededBOOL bEnable: Enable (TRUE) or disable?Return value: TRUE indicates success, FALSE failure.*****************************************************************/
BOOL
LoggedSetLockPagesPrivilege(HANDLE hProcess,BOOL bEnable)
{struct {DWORD Count;LUID_AND_ATTRIBUTES Privilege[1];} Info;HANDLE Token;BOOL Result;// Open the token.Result = OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES,&Token);if (Result != TRUE){_tprintf(_T("Cannot open process token.\n"));return FALSE;}// Enable or disable?Info.Count = 1;if (bEnable){Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;}else{Info.Privilege[0].Attributes = 0;}// Get the LUID.Result = LookupPrivilegeValue(NULL,SE_LOCK_MEMORY_NAME,&(Info.Privilege[0].Luid));if (Result != TRUE){_tprintf(_T("Cannot get privilege for %s.\n"), SE_LOCK_MEMORY_NAME);return FALSE;}// Adjust the privilege.Result = AdjustTokenPrivileges(Token, FALSE,(PTOKEN_PRIVILEGES)&Info,0, NULL, NULL);// Check the result.if (Result != TRUE){_tprintf(_T("Cannot adjust token privileges (%u)\n"), GetLastError());return FALSE;}else{if (GetLastError() != ERROR_SUCCESS){_tprintf(_T("Cannot enable the SE_LOCK_MEMORY_NAME privilege; "));_tprintf(_T("please check the local policy.\n"));return FALSE;}}CloseHandle(Token);return TRUE;
}
http://www.dtcms.com/a/522062.html

相关文章:

  • 河南郑州做网站的公司免费咨询律师在线
  • 网站建设 国际 深圳大型网站权限设计
  • word如何做网站营销推广软件
  • 用dw可以做网站吗广告设计公司实践报告
  • 网站制作素材图片杭州专业做网站公司
  • 东莞优化网站关键词优化帮忙做简历的网站
  • 网站怎么做必须交钱吗免费传奇网站免费传奇
  • 用文字写美食个人网站设计作品网上购物有哪些网站?
  • 做电影网站怎么样手机网站域名查询
  • wordpress网站模版网站空间一年多少钱
  • 做第三方seo优化网站网站购物车建设
  • 网站运营效果分析怎么做网站流量成本
  • 郑州哪家公司做网站山东省最新消息今天
  • 西安网站建设云阔网络熊掌号青岛建网站的公司
  • 网站制作公司哪儿济南兴田德润有活动吗福建省建设执业资格管理注册中心网站
  • 网站开发 技术投标江苏宿迁租房网
  • 在MySQL中,一条SQL语句的执行全流程是怎样的?
  • 中国专利查询系统入口seo服务外包公司
  • 淘宝上的网站怎么做先做产品网站还是app
  • 专做丰田车货款的网站建设电影网站需要什么
  • 网站建设都有什么技术支持上海网站备案流程
  • 网站改名字 收录网站建设费用贵不贵
  • 建设网站有哪些方法上海房屋装修公司实力排名
  • 绵阳做网站公司如何建设网站兴田德润怎么联系
  • 【多模态】46、DeepSeek-OCR | 一张图片是否真能抵千词
  • 蒙文网站建设的意义网站建设服务 行业代码
  • 网站设计谈判python开源代码网站
  • RK Android15 删除下拉状态栏(QuickSettings)中某些图标的修改
  • Android bind service使用Binder 池的方法
  • 没有网页快照对网站有什么影响如何自己建设网站