概要
最近在做QT项目时需要在表格上显示大量数据,并且需要一次性取到所有数据,还不能使用分页,刚好看到Microsoft官方有对虚拟内存的申请方法,试一试如何利用QT的tableModel和虚拟内存结合使用,从而降低物理内存的占用率,先简单记录一下虚拟内存的操作方法。
虚拟内存的申请和释放
Windows系统提供了专门的虚拟内存申请和释放的接口,只需要调用两个函数即可,参考:https://learn.microsoft.com/zh-cn/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc
内存的申请代码如下:
void *memoryPtr = VirtualAlloc(nullptr,
dataSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
每个参数的意义就不细说了,官方文档是写得非常细的。
内存的释放代码如下:
VirtualFree(memPtr, 0, MEM_RELEASE);
对象创建和释放
通过虚拟内存的申请后获得了一个地址,只需要将对象申请到该地址上即可
void *memoryPtr = VirtualAlloc(nullptr,
dataSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
auto *myClass = new(memoryPtr) MyClass; //MyClass为自定义对象
new其实是C++语法对malloc封装的运算符,上述代码中表示构造一个MyClass对象到指定地址上,在这里也可以通过重写MyClass对象的operator new来实现,后续有空了再单独写一下。
释放的话可能需要收到调用析构函数,之后再申请释放这块内存
myClass ->~MyClass();
VirtualFree(myClass, 0, MEM_RELEASE);
技术细节
1.申请虚拟内存后需要判断返回的地址是否为空,防止虚拟内存申请失败
2.回收对象时一定要手动调用析构函数,再调用Windows的VirtualFree函数,刚才也说过:new和delete只是C++语法对malloc和free的封装运算符,所以也可以手动重写operator new和operator delete函数来实现。
3.如果在你的自定义类中使用了QByteArray、QVector、QString之类的变量,这些对象中储存的数据只会在堆内存中,并不会与你的对象在连续的空间中,所以需要利用数组手动管理数据。可以利用可变结构体实现,后续有空也会另外写一篇。