内存管理

动态内存管理 malloc函数与free函数

你离开我真会死。 提交于 2020-02-20 03:02:02
创建动态内存空间函数malloc: 函数原型: - void *malloc(size_t size); 需要头文件<stdlib.h>; malloc函数向系统中申请分配size个字节的内存空间,并返回一个指向这块空间的指针。 返回值为void类型的原因:因为void是可以转换(赋值)为任意一种类型的,是由于我们申请内存空间的不确定性。 注意:申请的空间没有被初始化为零,所以所申请的空间内的数据是随机的。 如果函数调用成功,返回一个指向申请内存空间的指针,返回类型是void,所以可以被转换为任意类型的数据。 如果函数调用失败,返回值是NULL。如果设置size为0,也有可能返回为NULL,这不代表函数调用的失败。 调用malloc函数的例子: #include <stdio.h> #include <stdlib.h> int main() { int *ptr; //定义指针ptr ptr = (int *)malloc(sizeof(int)); //地址给ptr记载 (int *)可以省略 if (ptr == NULL) { printf("分配内存失败!\n"); exit(1); //程序退出 } printf("请输入一个整数:"); scanf("%d",ptr); printf("你输入的整数是:%d\n",*ptr); return 0; }

JVM内存管理

一世执手 提交于 2020-02-19 02:17:09
什么是java内存管理? 首先jvm的运行时数据区域可以划分为堆,栈,方法区,程序计数器。栈又分为虚拟机栈和本地方法栈。 虚拟机栈中存放栈帧,每一个栈帧中存有局部变量表,操作数栈,动态连接等信息,java方法从开始到结束代表着栈帧的一次入栈出栈操作。本地方法栈是为native方法服务的。 程序计数器:当前线程执行字节码时的行号指示器。 堆:用来存放数组和实例化的对象。 方法区:用来存储类信息,final常量,static静态变量,即时编译器编译的代码等,其中还包括运行时常量池,用来存放字面量和符号引用。 其中堆内存比较重要,可能发生的问题是内存泄露或者是内存溢出。内存泄漏是指GC没有回收掉废弃对象导致一直占用空间。内存溢出是指堆内存已满。 垃圾回收策略: 引用计数法,可达性分析法。 标记清除算法,标记整理算法,复制算法,分代算法。 永久代的GC主要回收废弃变量和无用的类。 分代的原因是提高GC性能 每一次GC,90%的对象被回收 根据对象寿命可以分为新生代和老年代。新生代表示对象生命周期短,被回收几率高,主要是Minor GC,老年代表示对象寿命周期长,回收几率低。新生态中主要使用复制算法,老年代主要使用标记清除或标记整理算法。 新生代还可以分为Eden和Survivor区域。一块Eden和两块Survivor。复制算法的一种改进。

物理内存和虚拟内存

十年热恋 提交于 2020-02-16 19:22:56
1.物理内存和虚拟内存 直接从物理内存读取数据比从硬盘读写数据要快得多,因此,我们希望所有的数据的读写在内存中完成,但是内存是有限的,这样就引出了物理内存与虚拟内存的概念。 物理内存是系统硬件提供的内存大小,是真正的内存。虚拟内存是为了满足物理内存不足而提出的策略,利用磁盘空间虚拟出一块逻辑内存,用作虚拟内存的磁盘空间称为交换空间。 作为物理内存的扩展,Linux未在物理内存不足时,使用交换分区的虚拟内存(内核将暂时不用的内存块信息写到交换空间,物理内存得到释放并能用于其他地方,当需要用到原始内容时,这些信息会被重新从交换空间读入物理内存)。 Linux的内存管理采取的是分页存取机制。为了保证物理内存能得到充分利用,内核在适当时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,经常使用的信息保留到物理内存中。 2.深入了解Linux内存运行机制: 首先,Linux系统会不时地进行页面交换操作,以保持尽可能多的空闲物理内存。即使并没什么事情需要内存,Linux也会交换出暂时不用的内存页面,可以避免等待交换所需的时间。 Linux 进行页面交换时不是多有的页面在不用时都交换到虚拟内存中。Linux内核根据“最近经常使用”算法,仅仅将一些不经常使用的页面文件交换到虚拟内存中。有时我们会看到这么一个现象:Linux物理内存还有很多,但是交换空间也使用了很多

python 基础笔记 — 内存管理和垃圾回收

回眸只為那壹抹淺笑 提交于 2020-02-15 15:34:45
1、 变量的定义   (1) python变量使用前无须声明(Java/C等语言使用变量前必须先声明)   (2) 变量的 类型 无须显示声明(解释型语言在给变量赋值时,自动确认类型和内存占用情况) 2、内存管理   在为变量分配内存时,其实是在借用系统资源,因此在用完之后应该释放借用的系统资源。Python 解释器承担了内存管理的复杂任务,减轻了程序员的对内存操作的压力。   为了保持追踪内存中对象,Python 引入了 引用计数 这一技术。简单地说,当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 这个对象的引用计数变为 0 时, 它被垃圾回收。    引用增加:     (1)对象被创建   如:x = 3.14     (2)或另外的别名被创建 如: y = x (3) 或被作为参数传递给函数(新的本地引用) 如: foobar(x)     (4) 或成为容器对象的一个元素 如: myList = [123, x, 'xyz']    引用减少:     (1)一个本地引用离开了其作用范围。比如 foobar()(参见上一下例子)函数结束时。     (2) 对象的别名被显式的销毁。  如: del y # or del x     (3) 对象的一个别名被赋值给其它的对象   如:x = 123     (4)对象被从一个窗口对象中移除  如

浅谈Windows虚拟内存

橙三吉。 提交于 2020-02-15 10:54:16
  本人电脑2G内存,写程序打开很多窗口电脑都能正常使用,就是一般看个2、3个小时的电影,电脑才会出现内存不足的情况,以前在学校也帮老师装过SqlServer2008,我老师的C盘不是盖的,可不是一般的小,他的是winXP系统,装sql时总报内存不足,我上网查了下资料,将其虚拟内存temp文件夹移到了D盘才勉强装上Sql,今天针对我的电脑Win7系统,从网上找了些资料,发现问题还挺大的,特地与大家分享....    1、何为虚拟内存?   内存在计算机中的作用很大,电脑中所有运行的程序都需要经过内存来执行,如果执行的程序很大或很多,就会导致内存消耗殆尽。为了解决这个问题,Windows运用了虚拟内存技术,即拿出一部分硬盘空间来充当内存使用,这部分空间即称为虚拟内存,虚拟内存在硬盘上的存在形式就是 PAGEFILE.SYS 这个页面文件。   虚拟内存只是真实内存不足的补充,所以不要加以神化,虚拟内存的读写性能(即硬盘的读写)只有真正内存性能的几十分之一,而且对硬盘损伤很大!能不用则不用,能少用则少用!原则是够用+留少量余量即可。    2、虚拟内存设置的误区   其一:虚拟内存越大越好?   答案:错。虚拟内存过大,既浪费了磁盘空间,又增加了磁头定位的时间,降低了系统执行效率,没有任何好处。正确设置可节省256MB-4G左右空间(视内存大小)   其二:虚拟内存不应该设在系统盘C盘

Linux内存管理-高端内存(一)

江枫思渺然 提交于 2020-02-15 00:58:06
高端内存是指物理地址大于 896M 的内存。对于这样的内存,无法在“内核直接映射空间”进行映射。 为什么?   因为 “内核直接映射空间”最多只能从 3G 到 4G,只能直接映射 1G 物理内存,对于大于 1G 的物理内存,无能为力 。   实际上,“内核直接映射空间”也达不到 1G, 还得留点线性空间给“内核动态映射空间” 呢。   因此,Linux 规定 “内核直接映射空间” 最多映射 896M 物理内存 。   对于高端内存,可以通过 alloc_page() 或者其它函数获得对应的 page,但是要想访问实际物理内存,还得把 page 转为线性地址才行(为什么?想想 MMU 是如何访问物理内存的),也就是说,我们需要 为高端内存对应的 page 找一个线性空间,这个过程称为高端内存映射。 高端内存映射有三种方式: 1、 映射到“内核动态映射空间”   这种方式很简单,因为通过 vmalloc() ,在“内核动态映射空间”申请内存的时候,就可能从高端内存获得页面(参看 vmalloc 的实现),因此说 高端内存有可能映射到“内核动态映射空间” 中 。 2、 永久内核映射   如果是通过 alloc_page() 获得了高端内存对应的 page,如何给它找个线性空间?    内核专门为此留出一块线性空间,从 PKMAP_BASE 到 FIXADDR_START

内存管理:如何避免内存溢出和频繁的垃圾回收?

老子叫甜甜 提交于 2020-02-14 01:41:54
自动内存管理机制的实现原理 做内存管理,主要需要考虑 申请内存和内存回收 这两个部分。 申请内存的逻辑非常简单: 1、计算要创建对象所需要占用的内存大小; 2、在内存中找一块儿连续并且是空闲的内存空间,标记为已占用; 3、把申请的内存地址绑定到对象的引用上,这时候对象就可以使用了。 内存回收 内存回收需要做这样两件事儿: 1、先是要找出所有可以回收的对象,将对应的内存标记为空闲 2、整理内存碎片。 采用GC算法找出可回收对象,此类算法大多采用 “标记-清除“ 算法或其变种,此类算法分为标记和清除两阶段: 标记阶段:从 GC Root 开始,你可以简单地把GC Root 理解为程序入口的那个对象,记所有可达的对象,因为程序中所有在用的对象一定都会被这个 GC Root 对象直接或者间接引用。 清除阶段:遍历所有对象,找出所有没有标记的对象。这些没有标记的对象都是可以被回收的,清除这些对象,释放对应的内存即可。 缺点: 效率不高、空间问题、在执行标记和清除过程中,必须把进程暂停(Stop the world)。 java虚拟机中常见的垃圾收集器及其对应垃圾收集算法: 垃圾收集器 1、 Serial收集器。 (虚拟机运行在Client模式下的默认新生代收集器) 单线程收集器,在进行垃圾收集时,必须暂停所有其他的工作线程,直至结束。 2、 ParNew收集器 Serial收集器的多线程版本

Virtualbox源码分析23 NEM(Hyper-V兼容)4 VMExit

可紊 提交于 2020-02-14 00:26:19
Native execution manager (VMExit) 文章目录 Native execution manager (VMExit) 23.1 EPT内存管理 23.1.1分配内存 23.1.2 Unmap内存 23.1.3 修改内存属性和页面Map关系 23.2 VMExit处理 nemHCWinStopCpu nemHCWinHandleMessage nemHCWinCopyStateFromX64Header nemHCWinHandleMessageMemory nemHCWinHandleMessageIoPort nemHCWinHandleMessageInterruptWindow nemHCWinHandleMessageCpuId nemHCWinHandleMessageMsr nemHCWinHandleMessageException nemHCWinHandleMessageUnrecoverableException 本篇重点介绍NEM模式的处理VMExit的函数,基本框架和HM/Raw-mode完全一样,只是具体实现代码(调用的API)不同而已。 23.1 EPT内存管理 NEM内存管理,NEM模式的内存管理和HM模式的内存管理方法一样,EPT表也是由PGM维护,只不过当EPT表修改的之后(分配EPT内存,释放EPT内存

操作系统内存管理机制和Python垃圾回收机制 学习笔记

限于喜欢 提交于 2020-02-13 20:44:14
操作系统内存管理机制和Python垃圾回收机制 什么是分页机制 什么是分段机制 分段和分页的区别 什么是虚拟内存 什么是内存抖动 Python垃圾回收机制原理 什么是分页机制 逻辑地址和物理地址分离的内存分配管理方案 程序的逻辑地址划分固定大小的页 物理地址划分为同样大小的帧 通过页表和对应逻辑地址和物理地址 什么是分段机制 分段是为了满足代码的一些逻辑需求 数据共享、数据保护、动态链接 通过短标来对应逻辑地址和物理地址 每个段内部是连续的内存分配,段和段之间是离散分配的 分段和分页的区别 页是出于内存利用率的角度提出的离散分配机制 段是出于用户的角度,用于数据保护,数据隔离等用途的管理机制 页的大小是固定的,操作系统决定;段大小不确定,用户程序确定 什么是虚拟内存 通过把一部分暂时不用的内存信息放到硬盘上 局部性原理,程序运行时只有部分必要的信息装入内存 内存中暂时不需要的内容放到硬盘上 系统似乎提供了比实际内存大得多的容量,称之为虚拟内存 什么是内存抖动 本质上是频繁的页调度行为 频繁的页调度,进程不断产生缺页中断 置换了一个页,又不断再次需要这个页 运行的程序太多;页面替换策略不好,终止进程或增加物理内存 Python垃圾回收机制原理 python无需我们手动回收内存 引用计数为主(缺点:循环引用无法解决) 引用标记清除和分带回收解决引用计数的问题 引用计数为主

(2) JVM内存管理:垃圾回收

我的未来我决定 提交于 2020-02-13 09:27:21
回顾上期 1)JVM中引用存在哪里? 答:虚拟机栈,该内存空间线程独有 2)该引用的对象存在哪里? 答:堆,所有通过new方法分配的对象都存在堆中 3)String s1="abc",字符串"abc"存在哪里? 答:运行时常量池,且常量池每次存储对象时会查找是否存过相等的对象,如果有,直接引用指向它,不再开辟空间。 如果你三个问题都可以回答出来,恭喜你!上一篇的精髓你get到了~~~~ 引用的分类 1) 强引用,默认分配方式均为此类型 Object a=new Object(); 2) 软引用,以强引用为参数,构造弱引用 Object a=new Object(); SoftReference<Object> b=new SoftReference<Object>(a); a=null; //强引用a一定要断掉 System.out.println(b.get()); //通过get()方法返回对象 3) 弱引用 Object a=new Object(); WeakReference<Object> b=new WeakReference<Object>(a); a=null; //强引用a一定要断掉 System.out.println(b.get()); //通过get()方法返回对象 System.gc(); 4)幽灵引用,和没有引用是一样的 引用的特点 1