快乐虾
http://blog.csdn.net/lights_joy/
lights@hb165.com
本文适用于
Xp sp3
vs2008
欢迎转载,但请保留作者信息
我们都知道在程序里可以使用malloc在堆上分配内存,显然windows应该为这个Heap分配一块空间的,我们在主程序里用malloc分配一小块内存,看看指针指向哪里:
char* p = (char*)malloc(10);
得到一个指针:0x00b267b0
在内存块里面找,很容易就发现了目标:
基址
|
分配基址
|
分配保护
|
大小
|
状态
|
保护
|
类型
|
00b20000
|
00b20000
|
00000004 PAGE_READWRITE
|
00007000
|
00001000 MEM_COMMIT
|
00000004 PAGE_READWRITE
|
00020000 MEM_PRIVATE
|
00b27000
|
00b20000
|
00000004 PAGE_READWRITE
|
00009000
|
00002000 MEM_RESERVE
|
00000000
|
00020000 MEM_PRIVATE
|
从这里可以发现malloc采用的算法并不会在一开始就分配一块很大的内存,如果我们接着用:
p = (char*)malloc(0x10000);
分配一块64K的内存,这时可以发现又多了一块内存:
基址
|
分配基址
|
分配保护
|
大小
|
状态
|
保护
|
类型
|
00cd0000
|
00cd0000
|
00000004 PAGE_READWRITE
|
00012000
|
00001000 MEM_COMMIT
|
00000004 PAGE_READWRITE
|
00020000 MEM_PRIVATE
|
00ce2000
|
00cd0000
|
00000004 PAGE_READWRITE
|
000ee000
|
00002000 MEM_RESERVE
|
00000000
|
00020000 MEM_PRIVATE
|
而这块内存在第一次分配时是空闲的。
由此可以猜测,malloc可以分配得到的最大内存块应该取决于最大的空闲块。写段代码测试一下:
void block_test()
{
SYSTEM_INFO info;
MEMORY_BASIC_INFORMATION mi;
HANDLE hProcess;
DWORD dwAddr;
MEMORY_BASIC_INFORMATION miBlock[1000];
int nCount = 0, nMaxSize = 0;
char* p = NULL;
hProcess = GetCurrentProcess();
GetSystemInfo(&info);
dwAddr = (DWORD)info.lpMinimumApplicationAddress;
do
{
VirtualQueryEx(hProcess, (LPCVOID)dwAddr, &mi, sizeof(mi));
memcpy(&miBlock[nCount++], &mi, sizeof(mi));
dwAddr += mi.RegionSize;
if((mi.State & MEM_FREE) && mi.RegionSize > nMaxSize)
nMaxSize = mi.RegionSize;
} while(dwAddr < (DWORD)info.lpMaximumApplicationAddress);
p = malloc(nMaxSize);
………..
}
得到的nMaxSize = 0x34c1 0000,但是内存分配失败,么回事?跟踪一下malloc的执行过程,发现在执行过程中有这样的调整:
blockSize = sizeof(_CrtMemBlockHeader) + nSize + nNoMansLandSize;
经过这样的调整,blockSize就变成了0x34c1 0024,所以分配失败。
我们将这个大小略作调整:
p = malloc(nMaxSize – 0x24);
还是分配失败。
想想,如果windows要将一个空闲块用作heap,那么想必需要写入一些辅助信息,咱再把这个大小调小一点:
p = malloc(nMaxSize – 0x124);
哈哈,终于成功了!咱终于分配了885M的内存。
难怪windows要将这些系统DLL尽量往高处放!
趁热打铁,咱创建一个最简单的console application,这样就没有太多的DLL来进行干扰。再运行上面的代码,这样可以得到一个最大的内存块大小0x6c4d d000,期望能够直接分配,但是--------失败了!
考虑windows的内存块分配是以0x10000进行对齐的,尝试分配0x6c4d0000,这回可算成功了,哈哈,咱就有了1.8G的空间!但是malloc函数的执行过程超慢,过了足足十几秒才分配成功,不知道它到底还要做些什么工作。而且其它程序的运行就此变成蜗牛速度,呵呵。
顺带说一下,俺只有2G内存。
xp下用户程序空间分配(6):加载用户DLL(2009-8-28)
xp下用户程序空间分配(5):加载系统DLL(2009-8-27)
xp下用户程序空间分配(4):加载主程序(2009-8-27)
xp下用户程序空间分配(3):加载文件(2009-8-26)
xp下用户程序空间分配(2):栈(2009-8-26)
xp下用户程序空间分配(1):大致框架(2009-8-26)
分享到:
相关推荐
oracle:Heap size 3597K exceeds notification threshold 解决方法
java.lang.OutOfMemoryError: Java heap space 解决方法
搜集整理关于java错误处理:java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: Java heap space 资料整理
记录java.lang.OutOfMemoryError:Java heap space的情况 文章内容: 一.问题描述+原因分析+解决方案 二.JVM调优说明 三.Tomcat添加到jvisualvm监控
Myeclipse下java.lang.OutOfMemoryError Java heap space的解决
java虚拟机OutOfMemoryError:Java heap space堆dump文件,可以直接用来分析。
NULL 博文链接:https://geyubin.iteye.com/blog/779330
heapdump分析工具------HeapAnalyzer: 2014年1月最新发布 用法: 在命令行执行 java -Xmx500m -jar ha453.jar
通过heapdump工具分析服务器堆分配问题
heap dump: heap dump文件是一个二进制文件,它保存了某一时刻JVM堆中对象使用情况。HeapDump文件是指定时刻的Java堆栈的快照,是一种镜像文件。
heap Analyzer heapdump分析工具
IBM的HeapAnalyzer IBM的HeapAnalyzer IBM的HeapAnalyzer
this is the implementation of heap data structure
iOS 拦截奔溃 使程序不在崩溃 使用Runloop起死回生 拦截崩溃信息 传到服务器
解决Java_heap_space问题
在一些平台上,在有些情况下,javacore也被称为javadump,它包含jvm和应用程序相关的在特定时刻的一些诊断信息,如操作系统,应用程序环境,线程,native stack本地堆,锁,和内存的信息。在生成heapdump文件的时候...
最初的方案是在,Was启动后和发生死机时,使用HeapDump来分析具体程序调用的Java对象。但时间的快照文件却非常难以分析发生宕机时候内存堆内具体的变化情况。由于,需要准确定位到java虚拟机中堆栈的使用情况。由此...
xp 关于堆的申请分配 研究缓冲区溢出的朋友会用的着的 分享一下 大家共同进步
报错 java.lang.OutOfMemoryError: Java heap 启动报错java.lang.ClassNotFoundException: 1catalina.org.apache.juli.FileHandler JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -...