精华内容
下载资源
问答
  • #include Windows.h #include stdio.h #include "iostream" ...// printf("%s:创建进程并将shellcode写入进程内存\r\n", proc); } int main(int argc, char* argv[]){ help(argv[0]); injection(); }
  • 内存申请过程

    2018-08-02 00:24:35
    当Eden空间足够时,内存申请结束。否则到下一步; JVM试图释放在Eden中所有不活跃的对象(minor collection),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区; Survivor区被...

    JVM会试图为相关Java对象在Eden中初始化一块内存区域;
    当Eden空间足够时,内存申请结束。否则到下一步;
    JVM试图释放在Eden中所有不活跃的对象(minor collection),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;
    Survivor区被用来作为Eden及old的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区;
    当old区空间不够时,JVM会在old区进行major collection;
    完全垃圾收集后,若Survivor及old区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”Out of memory错误”。

    展开全文
  • 内核对于有申请100M、200M大内存的连续地址时,如果基于伙伴系统分配是不太可行的,首先伙伴系统最大支持...所以有个方案就是将内存预留出来,比如8g预留出4g,专门用于大块内存申请,cblock就是实现的这个方案。 ...

        内核对于有申请100M、200M大内存的连续地址时,如果基于伙伴系统分配是不太可行的,首先伙伴系统最大支持11阶即即8M的内存,即使调整最大阶数,内核在初始化伙伴系统是也不能有存在多个大阶内存,如果被分配或者裂变后再申请就有可能申请不到。所以有个方案就是将内存预留出来,比如8g预留出4g,专门用于大块内存申请,cblock就是实现的这个方案。

    一、预留内存初始化

        

    nr_map:预留内存块计数

    addr:预留内存块的起始地址

    size:内存块大小

    type:内存块类型,我们常用的是BOOT_MEM_RAM

        这个全局变量是保存可以进行预留操作的物理内存起始位置和大小等信息。具体都有那些会添加到这个全局变量没有找全,以下是个人理解。首先找到一个地方就是mem初始化时候setup_arch()->arch_mem_init()->add_mem_addpart()->add_memory_region()add_memory_region()会把预留出来的大块连续的物理内存放入到这个全局变量。放在这个全局变量里的物理内存也不是全部预留,只是我们可以从这个块里来申请预留的内存。

       预留的内存大小我们是通过DTS文件解析获得。获得之后开始在boot_mem_map中选择一个可以申请的内存块申请预留的内存。

    这里暂时没看懂这个reserve_start为什么这么这么计算。紧接着将已申请的预留内存通过cmemblock_add()放在全局变量cmmblock来管理

     

    va_start:预留内存虚拟地址的起始地址

    va_end:预留内存虚拟地址的结束地址

    pfn_start:预留内存虚拟地址的起始帧号

    pfn_end: 预留内存虚拟地址的结束帧号

        接下来我们所有什么的大块内存只需要通过cmmblock来管理。

        向cmmblock插入预留内存并不是只有上面的流程可以插入,比如conplat_reserve_memory()函数也是预留了内存最后放入了cmmblock。

    二、大块内存申请cmmblock

    大块内存申请是我们公司自己实现的一个内存管理的一个模块,自己维护内存的分配与释放,并不经过伙伴系统或者slab。

        对上文提到的所有预留内存都通过初始化函数cmm_block_init()初始化到全局单链表cblock_head中,如下:

    block_start:预留内存的虚拟地址的开始地址

    block_end:预留内存的虚拟地址的结束地址

    free_size:预留内存大小 

    下面就是内存分配:

    void * __cmm_alloc_block(unsigned long size, unsigned int mid,const void *caller)
    {
    	struct cblock *block;
    	struct cblock_area *area;
    	void *addr = NULL;
    	int reclaim = CMM_FREE_PAGE_RECLAIM_STATE;
    	int nocache = 0;
    
    	size = PAGE_ALIGN(size);
    	area = cblock_area_cache_alloc();
    	if (unlikely(!area))
    		return NULL;
    
    	if (mid)
    		area->caller = caller;
    	else
    		area->caller = NULL;
    retry:
    	block = cblock_head;
    	if (block->free_size >= size)
    	{
    		addr = cblock_alloc_area(block,area,size,nocache);
    	}
    
    	if (!addr && block->next)
    	{
    		addr = cblock_alloc_area(block->next,area,size,nocache);
    	}    
    #ifndef CONFIG_64BIT
            if (likely(addr))
                atomic_long_add((long)(size >> 10), &reserved_num);                 
    #endif              
    	return addr;
    }
    

     cblock_area_cach_alloc()函数从一个area链表中获取一个area,如果没有从slab中获取猜测释放时会放入到链表中。

     

    static void *cblock_alloc_area(struct cblock *block, struct cblock_area *area, unsigned long size, int nocache)
    {
        /*
            block:全局预留内存链表
            area:申请的内存区域记录
            size:申请内存大小
        */
    	struct cblock_area *first;
    	unsigned long addr;
    	unsigned long addr_end;
    	unsigned long flags;
        /* 加硬终端锁 */
    	spin_lock_irqsave(&block->lock,flags);
        /* 预留内存大于剩余内存 */
    	if (size > block->free_size)
    		goto overflow;
    
    	if (!block->area_cache || size <= block->area_hole || nocache)
    	{
    		block->area_hole = 0;
    		block->area_cache = NULL;
    	}
    
    	addr_end = block->block_end;
    
    	if (block->area_cache)
    	{
    		first = block->area_cache;
    		addr = first->area_end;
    	}
    	else
    	{
    		addr = block->block_start;
    
    		if (!list_empty(&block->area_list))
    			first = list_first_entry(&block->area_list,struct cblock_area, list);
    		else
    			goto found;
    	}
    
    	while (addr + size > first->area_start && addr + size <=  addr_end)
    	{
    		if (addr + block->area_hole < first->area_start)
    			block->area_hole = first->area_start - addr;
    
    		addr = first->area_end;
    
    		if (list_is_last(&first->list, &block->area_list))
    		{
    			goto found;
    		}
    
    		first = list_entry(first->list.next, struct cblock_area, list);
    	}
    
    found:
    	if (addr + size > addr_end)
    		goto overflow;
        /* area记录所申请的内存起始和结束位置 */
    	area->area_start = addr;
    	area->area_end	= addr + size;
        /* 更新block的信息 */
    	block->free_size -= size;
    	block->area_cache = area;
    
    	cblock_insert_area(block,area);
    	spin_unlock_irqrestore(&block->lock,flags);
    
    	return (void *)addr;
    
    overflow:
    	spin_unlock_irqrestore(&block->lock,flags);
    	return NULL;
    
    }
    

    每个area记录申请的大内存信息,申请的这个area一共挂在两个表中,一个是单链表中,一个是红黑树中。

    展开全文
  • 动态内存申请(malloc, calloc, new)之分配虚拟内存空间和物理内存空间 1. 动态内存申请的底层系统调用 动态内存申请函数根据申请的内存大小选择不同的系统调用,小于128K选择brk系统调用分配内存,大于128K选择...

    动态内存申请(malloc, calloc, new)之分配虚拟内存空间和物理内存空间

    1. 动态内存申请的底层系统调用

    动态内存申请函数根据申请的内存大小选择不同的系统调用,小于128K选择brk系统调用分配内存,大于128K选择mmap系统调用,使用strace可以清晰追踪到系统调用。

    2. 虚拟地址空间和物理地址空间

    将虚拟内存地址映射到物理内存地址,叫做内存映射,映射关系缓存在一个叫页表的结构中,由MMU模块进行管理;MMU规定内存的映射最小单位,通常为4K, 每次映射,都需要关联4K或4K整数倍的内存空间。

    3. malloc和new调用mmap时仅仅申请虚拟地址空间

    调用malloc或new申请较大动态分配堆内存时(没有初始化操作),仅仅申请到虚拟地址空间,并不实际获得物理内存空间,因此实际的物理内存并没有消耗,只有应用进程访问虚拟地址空间时,才会触发缺页异常,才会导致内核实际去分配物理内存,并更新页表映射关系。使用下述代码进行测试(使用top和free工具):

    #include <iostream>
    #include <string.h> //memset
    #include <unistd.h> //sleep
    #define SIZE (80 * 1024 * 1024) //80M
    int main(void)
    {
    
        std::cout << "1---->sleep 10s" << std::endl;
        sleep(10);
    
        std::cout << "2---->sleep 10s end, begin malloc" << std::endl;
        char *buf = (char *)malloc(SIZE);
        //char *buf = (char *)new char[SIZE];
        if (!buf) {
            std::cout << "malloc failed" << std::endl;
            exit(1);
        }
    
        std::cout << "3---->sleep 10s" << std::endl;
        sleep(10);
    
        std::cout << "4---->sleep 10s end, begin init" << std::endl;
        memset(buf, 0, SIZE);
        std::cout << "5---->sleep 10s" << std::endl;
        sleep(10);
    
        std::cout << "6---->sleep 10s end, exit" << std::endl;
        return 0;
    }
    

    (1)初始时,系统剩余内存free=85M左右,应用程序占用VSZ=3M左右内存;
    在这里插入图片描述
    (2)malloc函数调用结束,系统剩余内存free=85M左右,应用程序占用VSZ=85M左右内存;说明malloc申请了虚拟地址空间,但是物理内存实际并没有分配;
    在这里插入图片描述
    (3)给申请到的空间使用memset进行初始化,系统剩余内存free=3M左右,应用程序占用VSZ=85M左右内存;说明只有应用进程去访问虚拟地址空间时,才会导致内核实际去分配物理内存;
    在这里插入图片描述
    ps: calloc和malloc的区别在于calloc分配完虚拟地址空间后马上进行初始化,这就造成实际物理内存的分配。

    4.系统内存不足处理机制

    (1)回收内存, 使用LRU算法进行内存页面回收;
    (2)swap换入换出,不常用内存可以通过交换分区暂时写到磁盘中;
    (3)OOM杀死占用大量内存的进程:当申请内存过大导致系统内存严重不足时,系统会kill掉进程,如下:
    a.out invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
    [] (unwind_backtrace+0x0/0xe0) from [] (dump_header.isra.13+0x4c/0x11c)
    [] (dump_header.isra.13+0x4c/0x11c) from [] (oom_kill_process.constprop .16+0x38/0x1e8)
    [] (oom_kill_process.constprop.16+0x38/0x1e8) from [] (out_of_memory+0x 22c/0x2a8)
    [] (out_of_memory+0x22c/0x2a8) from [] (__alloc_pages_nodemask+0x4c4/0x 63c)
    [] (__alloc_pages_nodemask+0x4c4/0x63c) from [] (filemap_fault+0x288/0x 3a4)
    [] (filemap_fault+0x288/0x3a4) from [] (__do_fault+0x50/0x3b4)
    [] (__do_fault+0x50/0x3b4) from [] (handle_pte_fault+0x22c/0x9bc)
    [] (handle_pte_fault+0x22c/0x9bc) from [] (handle_mm_fault+0x9c/0xac)
    [] (handle_mm_fault+0x9c/0xac) from [] (do_page_fault+0xdc/0x1c8)
    [] (do_page_fault+0xdc/0x1c8) from [] (do_PrefetchAbort+0x34/0x98)
    [] (do_PrefetchAbort+0x34/0x98) from [] (ret_from_exception+0x0/0x10)
    Out of memory: Kill process 10040 (a.out) score 749 or sacrifice child
    Killed process 10040 (a.out) total-vm:105628kB, anon-rss:96968kB, file-rss:0kB

    5.总结

    本文主要介绍linux系统下动态内存分配使用的系统调用mmap(大块内存使用),进而展示出虚拟地址空间和物理地址空间的映射,以及总结了进程通过 malloc等申请内存后,内存并不会立即分配,而是在首次访问时,才通过缺页异常陷入内核中分配内存。由于进程的虚拟地址空间比物理内存大很多,Linux 还提供了一系列的机制,应对内存不足的问题,比如内存回收、交换分区 swap换入换出 以及 OOM 等。

    展开全文
  • C语言动态内存申请

    千次阅读 2017-05-18 17:33:29
    C语言动态内存申请1.malloc 原型:void* malloc(size_t size) void free(void* pointer) 说明: malloc分配的是一片连续的内存空间,以字节为单位,不带任何类型信息 malloc实际分配的内存比请求的稍微多一点 当...

    C语言动态内存申请

    1.malloc

    1. 原型:void* malloc(size_t size) void free(void* pointer)
    2. 说明:

      1. malloc分配的是一片连续的内存空间,以字节为单位,不带任何类型信息
      2. malloc实际分配的内存比请求的稍微多一点
      3. 当请求的内存无法满足时,返回NULL
      4. 当free的参数为NULL时,函数直接返回
    3. 示例:

    int main()
    {
        int i = 0;
        int *p1 = (int*)malloc(5 * sizeof(int));  //malloc申请内存空间
    
        for(i = 0; i < 5; ++i)
        {
            /*打印申请的内存空间里的值,在windows下是随机数字,在linux下测试为0*/
            printf("p1[%d] = %d\n", i, p1[i]);
        }
    
        free(p1);
        return 0;
    }
    • 注:需要对每一次的内存申请和释放进行检查,确保不为NULL

    2. calloc

    1. 原型:void* calloc(size_t num_elements, size_t size)
    2. 说明:

      1. calloc的参数代表所返回内存的类型信息
      2. calloc会将返回的内存初始化为0
    3. 示例:

    int main()
    {
        int i = 0;
        int *p1 = (int*)malloc(5 * sizeof(int));
        short *p2 = (short*)calloc(5, sizeof(short));  //calloc申请内存空间并初始化
    
        for(i = 0; i < 5; ++i)
        {
            /*打印malloc和calloc申请的空间里的值,进行比较*/
            //calloc会初始化为0
            printf("p1[%d] = %d, p2[%d] = %d\n", i, p1[i], i, p2[i]);
        }
    
        free(p1);
        free(p2);
        return 0;
    }

    3.realloc

    1. 原型:void* realloc(void* pointer, size_t new_size)
    2. 说明:

      1. realloc用来修改一个原先已经分配好的内存大小
      2. 在使用realloc后应该使用其返回值
      3. 当pointer的第一个参数为NULL时,等价于malloc
      4. 在扩大的内存时,原有的数据保存,新增加的添加到末尾
    3. 示例:

    int main()
    {
        int i = 0;
        int *p1 = (int*)malloc(5 * sizeof(int));
        short *p2 = (short*)calloc(5, sizeof(short));
    
        for(i = 0; i < 5; ++i)
        {
            printf("p1[%d] = %d, p2[%d] = %d\n", i, p1[i], i, p2[i]);
        }
    
        p1 = (int*)realloc(p1, 10);  //对malloc申请的内存空间进行扩大
        putchar(10);
    
        for(i = 0; i < 10; ++i)
        {
            /*打印出来扩大后的内存空间的值,存放的是随机数*/
            printf("p1[%d] = %d\n", i, p1[i]);
        }
    
        free(p1);
        free(p2);
        return 0;
    }
    展开全文
  • 内存申请与堆内存申请

    千次阅读 2017-11-14 17:14:51
    申请与堆申请 #include "stdafx.h" #include int _tmain(int argc, _TCHAR* argv[]) { #if 0 //栈申请 int a; int *pa = &a; *pa = 100; printf("a = %d\n", a); //堆申请 int *p = (int *)malloc(sizeof...
  • JVM之内存申请过程

    千次阅读 2018-03-09 16:45:37
     2、当Eden空间足够时,内存申请结束。否则到下一步; 3、JVM试图释放在Eden中所有不活跃的对象(minor collection),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivo...
  • 结构体、结构体指针的内存申请 、CSDN输入不同红色的字体 内存区间 在c语言中有4个内存区间,分别是代码区、全局变量和静态变量区、堆区和栈区,这四个区间相互扶持成为好兄弟。本文着重涉及堆区,主要针对包括...
  • Unity内存申请和释放

    万次阅读 2014-10-28 15:06:41
    Unity内存申请和释放 发表于 Unity 2014-07-01 15:01 字数: 2396 阅读量: 43 1.资源类型 GameObject, Transform, Mesh, Texture, Material, Shader, Script和各种其他Assets。 2.资源创建方式...
  • 内存申请和释放及堆连续

    千次阅读 2016-12-21 22:54:10
    C语言有两种内存申请方式: 1、静态申请:当你声明全局或静态变量的时候,会用到静态申请内存。静态申请的内存有固定的空间大小。空间只在程序开始的时候申请一次,并且不再释放(除非程序结束)。 2、自动...
  • 内存申请的释放

    2012-04-18 22:07:19
    二、在自己所运行的函数内通过内存申请函数new或者malloc等申请的内存,需要记得手动释放,否则会造成内存泄露,导致内存耗光,死机等。 三、不要轻易释放不是自己手动申请的内存,因为你的释放可能会影响申请内存...
  • lua虚拟机内存申请与释放

    千次阅读 2016-07-04 12:39:42
    首先看lua虚拟机内存申请与释放
  • C内存申请函数

    千次阅读 2012-11-28 22:16:02
    C语言跟内存申请相关的函数主要有 alloca、calloc、malloc、free、realloc。  alloca是向栈申请内存,无需释放。   malloc分配的内存是位于堆中的,并且没有初始化内存的内容,因此基本上malloc之后都会...
  • c/c++动态内存申请与释放

    千次阅读 2018-08-09 09:43:59
    1,C中内存申请有哪些(标准库函数) 函数名 函数原型 作用 例子 二维数组的申请,释放 malloc void * malloc(size_t size) 动态内存的申请 函数本身不知内存类型,关心内存...
  • DSP中内存申请耗时对比

    千次阅读 2015-02-01 11:46:52
    最近在用DM6437做图像处理,里面用到了链表实现的堆栈操作,这就需要大量的内存申请、释放,感觉这段函数有点耗时,所以就对DSP中片内、片外内存申请,不同的内存申请函数(malloc,MEM_alloc,MEM_calloc)耗时做了...
  • (持续更新)关于linux内存相关的一些概念:物理地址,MMU,三级页表,内存管理的基本方式。以及内存申请的几种方法:malloc,kmalloc,__get_free_pages,vmalloc,slab。
  • C++---之动态内存申请new

    千次阅读 2019-06-26 17:07:31
    一、为什么需要动态内存分配? 在C++程序中,所有内存需求都是在程序执行之前通过定义所需的变量来确定的。...1.C++中通过new关键字进行动态内存申请 2.C++中的动态内存分配是基于类型进行的 3.del...
  • c++ 内存申请

    千次阅读 2015-12-24 17:58:22
    在用malloc()申请内存时,最好多申请一个单位的内存,不然会在free()时会出错,如下: (摘自以以为网上大牛例子) 今天碰到到了free函数释放内存的错误,而且真的很难搞懂,上网一搜,竟然还有类似的,按照...
  • 关于QT的内存申请和释放

    千次阅读 2017-11-03 14:47:46
    关于QT的内存申请和释放 进入QT gui 设计的学习也有大半年年了,在做关于QT项目时遇到过关于内存释放错误的问题,曾经一度纠结过!以下是个人关于qt内存管理机制的总结:   首先看一个类:  为了简单...
  • c++/c内存申请与释放

    千次阅读 2017-05-03 11:36:10
    c++内存申请与释放//new 表达式 string *sp = new string(" a value ") //分配并初始化一个string对象 string *arr=new string[10] //分配10个默认初始化的string对像//delete delete sp //销毁*sp 然后释放sp指向的...
  • C 内存申请和释放

    千次阅读 2012-03-15 23:21:30
    C语言跟内存申请相关的函数主要有 alloca,calloc,malloc,free,realloc,sbrk等. 其中alloca是向栈申请内存,因此无需释放. malloc分配的内存是位于堆中的,并且没有初始化内存的内容,因此基本上malloc之后,调用...
  • 全局变量堆内存申请顺序

    千次阅读 2015-12-05 15:15:13
    全局变量堆内存申请顺序 tmp-> cat 1.cpp /// @file 1.cpp /// @brief /// @author EastonWoo /// 0.01 /// @date 2015-12-05 #include #include #define _MAP______OK // 屏蔽出现段错误 bool test(); #...
  • Linux内存申请机制

    2019-11-10 10:21:10
    在linux上部署项目的时候可能会遇到这么一个错误,明明有内存,但是报Segment fault的内存错误,是什么原因呢? 错误原因毫无疑问就是分配内存的时候内存不足,但是使用free 命令去查看系统的内存占用却发现此时还有...
  • C++ 内存申请

    千次阅读 2018-09-06 13:01:41
    <3>malloc/free仅仅只是动态分配内存空间/释放空间,而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理成员)。 <4>malloc/free需要手动计算类型大小返回void*,malloc失败后返回0,而...
  • libc 内存申请和释放及堆连续检查

    千次阅读 2016-08-04 17:18:28
     C语言有两种内存申请方式: 1、静态申请:当你声明全局或静态变量的时候,会用到静态申请内存。静态申请的内存有固定的空间大小。空间只在程序开始的时候申请一次,并且不再释放(除非程序结束)。 2、自动...
  • C语言中内存申请函数

    2020-10-03 17:00:18
    在数据结构C中线性表的顺序存储和数组很类似,用一块连续的内存来存储数据,C中有动态申请内存函数malloc,这个函数前后都要参数,从下面程序中就能看到,首先要在前面用(类型 *)的格式来指明它指向的类型内存,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,383
精华内容 12,553
关键字:

内存申请