R中SQLite内存数据库未占内存?是否实际存储于磁盘?
问题
我在R中尝试创建SQLite内存数据库,运行程序后发现:创建内存数据库并填充含百万实数的表后,R的内存占用毫无变化。我怀疑所谓的“内存数据库”不实,实际是存储在磁盘上。
在Windows 11设备上,创建内存数据库并填充大表,删除用于构建表的矩阵(mat)后,内存占用与程序初始状态完全一致,看起来该内存数据库根本没占用任何内存。我这个判断正确吗?还是忽略了某些细节?
环境信息
- 操作系统:Windows 11
- R版本:4.3.1 Patched (2023-10-10 r85312 ucrt) -- "Beagle Scouts"
测试程序
library(DBI) library(RSQLite) sqlite_in_memory0 = function() { #This function measures memory usage via gc. mem_report = function() { mem_used = gc() sum(mem_used[, "(Mb)"]) } message('Memory: Before creating dfr: ', mem_report()) #Generate a data frame. mat = matrix(rnorm(1e8), ncol=10) dfr = as.data.frame(mat) rm(mat) gc() colnames(dfr) = letters[1:10] #Check size of dfr. print(paste('Size of dfr: ', format(object.size(dfr), units='Gb'))) message('Memory: After creating dfr: ', mem_report()) #Connect to an in-memory database. conx <- dbConnect(RSQLite::SQLite(), ":memory:") #Disconnect in-memory database on exit. on.exit(dbDisconnect(conx)) #Insert data. dbWriteTable(conx, 'dfr', dfr) message('\nMemory: After creating in-memory table: ', mem_report()) #Drop dfr. What is the effect on memory? rm(dfr) message('Memory: After rm(dfr): ', mem_report()) #Retrieve data from in-memory database. result <- dbReadTable(conx, 'dfr') message('dim(result):') print(dim(result)) message('Memory: After dbReadTable: ', mem_report()) } sqlite_in_memory0()
(注:原代码中pst为拼写错误,已修正为paste)
解答
你的判断不正确,SQLite的:memory:数据库确实是在内存中的,只是你用gc()统计内存的方式看不到它的占用,核心原因如下:
内存统计范围限制
gc()仅统计R自身垃圾回收器管理的内存,而SQLite内存数据库的内存是由底层C语言引擎直接向系统申请的,这部分内存不在R的监控范围内,自然不会出现在gc()的统计结果里。系统内存管理特性
Windows采用延迟内存提交机制,SQLite申请内存后,系统可能不会立即分配物理内存,直到数据实际写入时才会真正占用,但即便如此,这部分内存也不会被R的gc()捕获。验证内存数据库的有效方法
- 断开数据库连接后,再尝试读取表会直接报错,证明数据并未持久化到磁盘;
- 用Windows任务管理器查看R进程的内存占用(切换到“详细信息”标签),能看到插入数据后进程内存明显上升。
内容的提问来源于stack exchange,提问作者Argent
相关产品推荐
相关产品推荐

