精华内容
下载资源
问答
  • 进程内存分配图

    千次阅读 2017-04-24 16:19:24
    进程内存分配图 高地址                           低地址 段区名 解释 内容 stack 栈:局部变量 1在函数内部定义的局部变量(非static...

    进程内存分配图

    高地址

     

     

     

     

     

     

     

     

     

     

     

     

     

    低地址

    段区名

    解释

    内容

    stack

    栈:局部变量

    1在函数内部定义的局部变量(非static型)

    2中断发生时存放的运行环境

    room

    增长空间:堆向上长,栈向下长

    堆和栈动态变化的空间,堆从低地址向上动态增长;栈从高地址向下动态增长

    heap

    堆:动态分配的内存空间

    程序运行时动态分配的空间,如malloc函数、new等

    动态释放,如free函数,delete等

    other

    其他

     

    .bss

    未初始化全局变量区

    函数外部定义的如:1 int i;   

                      2 static int g;

    .data

    已初始化的全局变量区

    1函数外定义的:static int i=0;

    2函数内定义的:static int g;//编译器自动初始化为0

    .text

    可执行文件

    1程序代码,即当前CPU的二进制机器码

    2常量,如const char msg[]=”hello world\n”

     

     

    说明:

    (1)对于单片机来说,可执行文件一般没必要加载至内存中,那么也就不存在.text段区

    (2)对于多任务系统来说,一个进程的内存分配往往是动态的,因此堆区实际地址空间可能并不连续

    (3)栈区作为存放局部变量的区域,往往可以设置其最大大小,运行时超出定义大小则会产生越界错误

    展开全文
  • 1.3 练习: 画内存分析

    千次阅读 2019-11-08 12:18:15
    练习: 画内存分析,求出以下程序的结果。 int my_fun(int z) { z = z/5; return z; } int fun(int x,int y) { int c; c = x + y; my_fun(c); return c; } int main(int argc,char *argv[]) { int a = 10...

    练习: 画内存分析图,求出以下程序的结果。

    int my_fun(int z)
    {
    	z = z/5;
    	return z;
    }
    
    int fun(int x,int y)
    {
    	int c;
    	c = x + y;
    	my_fun(c);
    	return c;
    }
    
    int main(int argc,char *argv[])
    {
    	int a = 10,b = 5;
    	int ret = fun(a,b);
    	
    	ret = my_fun(ret);
    	printf("ret = %d\n",ret); //3
    	return 0;
    }
    

    1、形参和实参

    一、形参出现在函数定义中,在整个函数体内都可以使用,形参变量只有在被调用时才分配内存单元,在调用结束时即刻释放所分配的内存单元,因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。 离开该函数则不能使用,实参出现在主调函数中,进入被调函数后,实参变量也不能使用。

    二、形参和实参的功能是作数据传送。发生函数调用时,主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。

    三、实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。

    四、实参和形参在数量上,类型上,顺序上应严格一致,否则会发生“类型不匹配”的错误。

    五、实参和形参的数据传递方式有两种,

    1)一种是值传递,实参和形参都不是指针,这种情况下函数调用中发生的数据传送是单向的。 即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 在函数调用过程中,形参的值发生改变,而实参中的值不会变化。究其原因,是因为这两个参数在内存中位于不同的位置,值传递只是形参将实参的内容复制,在内存中被分配了新的内存单元,在函数执行完毕以后地址会立刻被释放掉,因此形参的改变不会对实参有任何影响。 2)另一种是地址传递,就是实参与形参共用同一个内存单元,在函数执行的过程中,实际就是对实参的地址进行操作,因此形参改变,实参同步变化,实际他们就是同一变量,因为在内存中占据的就是一个内存单元

    进行分析

    首先,这个函数并不存在地址传递,所以不需要考虑这个问题。下面这幅图是变量在内存中的存储方式:
    在这里插入图片描述

    首先进入main函数:

    【注】:int a;的含义是:在内存空间内申请了一段连续的四个字节的内存空间,并且通过a来访问该地址空间。
    首先此时定义了两个int型的变量,意义如下
    在这里插入图片描述
    然后执行int ret = fun(a,b);
    在这里插入图片描述
    此时调用了函数fun();通过前面的概念可得,此时我们需要给形参申请地址空间:
    在这里插入图片描述
    此时fun()函数中又调用了my_fun();函数:

    在这里插入图片描述
    此时my_fun();函数结束:
    将z所指向的那块地址空间释放:
    在这里插入图片描述
    接着结束fun()函数:
    在这里插入图片描述
    然后此时结束main()函数
    在这里插入图片描述
    此处还没写完。。。待续

    展开全文
  • JVM内存分配与管理详解

    万次阅读 2018-01-23 16:17:58
    了解C++的程序员都知道,在内存管理领域,都是由程序员维护与管理,程序员用于最高的管理权限,但对于java程序员来说,在内存管理领域,程序员不必去关心内存分配以及回收,在jvm自动内存管理机制的帮助下,不需要...

    概述

    了解C++的程序员都知道,在内存管理领域,都是由程序员维护与管理,程序员用于最高的管理权限,但对于java程序员来说,在内存管理领域,程序员不必去关心内存的分配以及回收,在jvm自动内存管理机制的帮助下,不需要想C++一样为每一个new操作去编写delete/free代码,这一切交给jvm,但正是这一切都交给了jvm,一旦出现内存泄漏与溢出,如果不了jvm,那么对于程序的编写与调试将会非常困难,因此了解jvm时怎样分配内存管理是非常关键的,下面我们来介绍一下Jvm内存区域的分配以及常见的内存溢出错误。

    一、运行时数据区域

    这里写图片描述

    1.程序计数器

    程序计数器是一块较小的内存空间,它可以看做当前线程所执行的字节码的行号指示器,在jvm中,虚拟机通过改变程序计数器的值来选取下一条需要执行的字节码的指令,分支,循环,跳转,异常处理,线程恢复等基础功能都需要依赖它。
    在java多线程中四通过线程轮流切片并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器都只会执行一条线程的指令,每一条线程都需要一个独立的程序计数器,各个计数器之间不相互影响,独立存储,因为这类内存区域称为“线程私有”的内存。此内存区域是唯一一个在jvm中没有规定任何OutOfMemoryError情况的区域。

    2.java虚拟机栈

    与程序计数器一样,java虚拟机栈也是线程私有的,它的生命周期与线程相同,虚拟机栈描述的是java方法执行的内存模型:每一个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储用于存储局部变量表,操作数栈,动态链接,方法出口等信息,每一个方法从调用到执行 完成的过程就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。局部变量表中存放着编译时期的各种基本数据类型(long/double,int,boolean,byte,char,short,float),对象引用(reference类型,它不等于对象本身,可能是指向对象的一个指针,也可能是一个指向对象的一个句柄或者其他与位置有关的信息)和returnAddress类型(指向了一条字节码指令的地址)。其中long和double类型的数据会占用两个局部变量空间(slot),其余数据类型只占用一个局部变量空间,局部变量表在编译时期完成分配,在方法运行期间不会改变局部变量表的空间大小。
    在java虚拟机栈中,规定了两种异常状况:
    StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度,将抛出该异常。
    OutOfMemoryError:如果虚拟机栈可以动态扩展,当无法申请过到足够的内存,就会抛出该异常。

    3.本地方法栈

    本地方法栈与虚拟机栈的作用相似,它们之间的区别在于java虚拟机栈为虚拟机执行java方法(字节码)服务,而本地方法栈为虚拟机栈使用到的Native方法服务(在SUN HotSpot虚拟机中将虚拟机栈和本地方法栈合二为一)。

    4.Java堆
    在Java虚拟机中,java堆是在这部分内存中最大的一块,java堆是被所有线程共享的一块内存区域,这部分内存用于存放对象的实例,几乎所有对象的实例都在这里分配内存。java堆同时也是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆(Garbage Collected Heap)”,从内存回收的角度来看,由于现在收集器基本都采用分代收集算法,所以java堆还细分为新生代和年老代,再细致点就是Eden空间,From Survivor空间,To Survivor空间等,从内存分配的角度来看,java堆有时还回创建一个多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB),但是无论如何分配,都与存放内容无关,都存放的是对象实例,只是为了更有利回收和分配内存,对java堆的内存,可以是一块连续的内存,也可以是不连续的内存,只要逻辑上连续即可,在实际中,这部分内存既可以是固定的内存,也可以是可扩展的(可以通过-Xmx和-Xms控制),如果在堆中没有内存完成实例的分配,并且堆也无法扩展,将会抛出OutOfMemoryError异常。

    5.方法区

    方法区与java堆一样,都是线程共享的内存区域,它用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。尽管有时候jvm将方法区描述为堆的一个逻辑部分,但是它有一个别名Non-Heap(非堆),用来与堆进行区分。对于方法区,将它划分为“永久代”,因此这部分可以不实现垃圾收集,但并非这部分区域数据永久存在,这区域主要针对常量池的回收和对类型的卸载。当方法区无法满足内存分配需求的时候,将抛出OutOfMemoryError异常。

    6.运行时常量池

    运行时常量池是方法区的一部分,在class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项信息就是常量池(Constant Pool Table),用于存放编译器生成的各种字面量和符号引用,这部分内容在类加载后进入方法区的运行时常量池中存放。常量池的另外一个重要的特性就是具有动态性,java语言并不要求常量一定只有在编译期间才能产生,也就是说并非只有在class文件中常量池中的内容才能放入运行时常量池中,也可以在程序运行期间将新的常量放入池中。当常量池中无法再申请到内存时会抛出OutOfMemoryError异常。

    二、对象的创建

    1.对象的创建

    java作为一种面相对象的编程语言,在程序运行期间无时无刻不在创建着对象的实例,通过new关键字来创建对象的实例,那么这个过程是怎样的呢?下面来让我们一起探讨一下。

    在jvm遇到new关键字后,首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且去检查这个符号引用代表的类是否已被加载,解析和初始化过,如果没有就必须先执行类加载的全过程。在类加载检查后,jvm将会为新生对象在java堆中分配内存,对象所需要的内存大小在类加载的过程中即可完全确定。
    在堆中对内存的分配可以分为两种方式,如果堆中的内存时连续的规整的,那么所有使用的内存放在一边,没有使用的内存放在另一边,中间放着一个指针作为分界的指示器,当为对象分配内存的时候,只需将指针移动,划分出一块没有使用的内存即可,这种分配方式成为“指针碰撞”。另一种方式是堆中的内存并不规整,所有的空闲内存都存储在一块空闲列表中,当为对象分配内存时只需更新该列表即可,这种分配方式成为“空闲列表”。选择哪种分配方式由堆的内存是否规整来决定。
    在这里还有一点需要注意的是对象的创建时一个非常频繁的操作,当程序处于高并发的状况下时就不能保证线程安全了,例如当为对象A分配内存,当指针还没有来得及修改时,对象B又同时使用了原来的指针来分配内存,当发生这种情况时,我们有两种解决方案:
    1)对分配的内存进行同步处理来保证操作的原子性。
    2)把内存分配的动作按照线程划分在不同的空间中,即每一个线程在java堆上预先分配一块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),哪个线程需要分配内存就现在这个线程的TLAB上分配。只有TLAB用完并且要分配新的TLAB时才需要同步锁定。jvm是否使用TLAB可以通过-XX:+/-UserTLAB参数来设定。

    2.对象的内存布局

    对象在内存中存储的布局可以分为三块区域:对象头(Header),实例数据(Instance Data)和对齐填充(Padding)。

    1)对象头

    对象头包括两部分信息:
    一部分是用于存储对象自身的运行数据,如哈希码(HashCode),GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等。
    另一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪一个类的实例。当对象是一个java数组的时候,那么对象头还必须有一块用于记录数组长度的数据,因此虚拟机可以通过普通java对象的元数据信息确定java对象的大小,但是从数组的元数据中无法确定数组的大小。

    2)实例数据中存储的是对象真正有效的信息。

    3)对齐填充这部分并不是必须要存在的,没有特别的含义,在jvm中对象的大小必须是8字节的整数倍,而对象头也是8字节的倍数,当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。

    三、对象的访问定位

    对于对象的访问方式有使用句柄和直接指针两种。
    1.使用句柄:

    这里写图片描述

    如果使用句柄,那么reference中存储的是对象句柄地址,java堆划分一部分内存作为句柄池,句柄中包括了对象实例数据与类型数据各自的具体地址信息。

    2.直接指针

    这里写图片描述

    直接使用指针,reference存放的就是对象地址,在java堆中就必须考虑如何放置访问实例的类型数据的信息。

    使用这两种访问方式,各有优劣,使用句柄最大的好处就是当对象被移动的时候只需要改变句柄的地址,无需修改reference。直接指针访问方式速度快,节省了很多开销对于频繁需要访问的对象。

    展开全文
  • C语言内存分布

    千次阅读 2018-05-24 10:48:58
    C语言内存分布原文章在这里:https://blog.csdn.net/love_gaohz/article/details/41310597一.在学习之前我们先看看ELF文件。ELF分为三种类型:.o 可重定位文件(relocalble file),可执行文件以及共享库(shared ...
  • 动态内存分配算法(详解加代码)

    千次阅读 2019-12-12 17:28:22
    动态内存分配主要有四种算法: (1) 首次适应算法:每次都从低地址开始查找,找到第一个能满足大小的空闲分区。 (2) 循环首次适应算法:首次适应算法每次要从头找,增加了查找的开销,也可能在低地 址上产生难以利用...
  • 最佳适应算法-内存分配

    千次阅读 2020-03-28 14:32:09
    在操作系统中,内存分配是非常重要的工作。 已知内存空间由N个内存块组成,这些内存块从1到N编号,进行内存分配时,操作系统将选择一块大小足够的内存全部分配给 请求内存的进程。例如,当进程请求10MB的内存时,...
  • 操作系统------资源分配图化简

    千次阅读 多人点赞 2019-10-03 15:40:24
    1.资源分配图: 2.资源分配图化简: 方法步骤 第一步:先看系统还剩下多少资源没分配,再看有哪些进程是不阻塞(“不阻塞”即:系统有足够的空闲资源分配给它)的; 第二步:把不阻塞的进程的所有边都去掉,...
  • 分 配 主 存 ,首次适应算法, 最佳适应算法 -主 存 回 收********
  • CSAPP Dynamic Storage Allocator 动态内存分配

    千次阅读 多人点赞 2019-01-14 18:09:04
    动态内存分配器 专 业 计算机科学与技术 计算机科学与技术学院 mm.c源代码见文章末尾 目 录 第1章 实验基本信息... - 4 - 1.1 实验目的... - 4 - 1.2 实验环境与工具... - 4 - 1.2.1 ...
  • java内存模型

    千次阅读 多人点赞 2018-11-09 13:09:55
    java内存模型 下就是java内存模型,但是一般讨论...接下来介绍下中两个线程内存分配的概念。 java里的堆是运行时的数据区,堆是由垃圾回收来负责的,堆的优势是可以动态的分配内存大小,生存期也不必事先告...
  • 要求模拟分区存储器中动态分区法,实现分区分配的三种算法:最先适应法,最佳适应法和最坏适应法。运行时可任选一种算法。系统应能显示内存分配的状态和参数变化情况。
  • 3.1.4 操作系统之内存分配与回收

    千次阅读 多人点赞 2020-04-23 21:32:09
    动态分区分配(可变分区分配)(1)系统要用怎样的数据结构记录内存的使用情况呢?(2)当多个空闲分区都能满足要求时,应该选择哪个分区进行分配?(3)如何进行分区的分配和回收操作?4.内部碎片与外部碎片 0....
  • C++各种变量内存分配

    千次阅读 2017-08-30 13:52:46
    程序在的内存中的分配(常量,局部变量,全局变量,程序代码)一. 在c中分为这几个存储区 1.栈 - 由编译器自动分配释放 2.堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 3.全局区(静态区),...
  • C语言内存分配 详解(附图)

    千次阅读 2013-10-06 15:52:09
    后来老大帮忙解决,发现是结构体内部的“成员结构体指针”被赋值成一个之前声明并初始化的局部变量引起的,在声明这个成员结构体指针的时候加上关键字“static”,问题就解决了,不会再出现看似内存错乱的问题。...
  • \qquad为了方便起见,存放三个按钮的数组我们合并为了一个二维数组,在鼠标事件中更容易使用和分配任务。 #include // 引用图形库头文件 #include #include #include //用到了定时函数sleep() #include int r[3][4]...
  • Java继承的内存分配

    千次阅读 多人点赞 2017-02-10 14:56:13
    今天,复习的是继承的内存分配。我们知道,Java中内存可以初略分为堆、栈、方法区。 package sort; class Person{ public int age; public String name; public Person(){ System.out.println("父类"); say...
  • 很详细,很复杂。不过貌似有点小问题,大家可以研究下!
  • C++经典面试之 内存分配的三种方式

    千次阅读 2018-05-16 15:55:51
    要回答这个问题,我们必须先要理解C++的内存管理方式,需要站在内存四区的角度去审视一下代码,这样整个理解了内存分配的方式,回答的时候就只需要注意一些细节了。写一个例子然后一下内存示意。...
  • 典型C内存空间分布

    千次阅读 2017-02-05 20:27:45
    典型C内存空间分布 bss段,data段,代码段(.text),堆(heap),栈(stack)
  • 内存分配的三种方式

    万次阅读 2018-08-14 14:57:58
    要回答这个问题,我们必须先要理解C++的内存管理方式,需要站在内存四区的角度去审视一下代码,这样整个理解了内存分配的方式,回答的时候就只需要注意一些细节了。写一个例子然后一下内存示意。 int getmem...
  • slub分配内存原理5. slub释放内存原理6. kmalloc作者简介:宋牧春,linux内核爱好者,2017年6月本科毕业于江苏大学。现就职于一家手机研发公司,任职BSP驱动工程师,主要负责TP驱动bringup和调试。1. 前言在Linux中...
  • 如果想对对象操作的过程进行内存分析,首先要了解两块内存空间的概念:堆内存:保存每一个对象的属性内容,堆内存需要用关键字new才能开辟。栈内存:保存的是一块堆内存的地址。 堆内存很好理解,可能有人会有疑问为...
  • 动态分配内存空间过程

    千次阅读 2013-10-19 22:10:22
    动态分配内存空间过程 本篇文章仅以一个非常短小的程序进行讲解。 C编译系统提供4个内存动态分配函数:calloc(),malloc...Void *malloc(size):这是一个指针型函数,用来按字节数申请内存分配。如申请100个整数的内
  • 全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
  • 内存分布

    千次阅读 2012-11-01 16:03:29
    开机时系统会以实模式进入,此时可访问的内存只有1M大小,这时的内存分配情况如下所示(此时由bios主导这一M内存的使用情况): 0x 0 0 0 0 0 | | 10x64K=640K; 基本内存 | 0x 9 F F F F 0x A 0 0 0 0 | ...
  • 内存映像

    千次阅读 2018-02-01 15:10:29
    内存映像图内存映像象内容权限栈区函数中的普通变量可读可写堆区动态申请的内存可读可写静态变量区static修饰的变量可读可写数据区用于初始化变量的常量只读代码区代码指令只读1. 栈区:普通变量(非new, 非const....
  • 操作系统-动态内存分配算法

    千次阅读 2017-12-02 14:46:55
    内存分配算法 1、首次适应算法(FF) 2、循环首次适应算法(NF) 3、最佳适应算法(BF) 4、最坏适应算法(WF) 本程序使用前端技术实现(html+css+JavaScript)新建以下文件在同一目录:index.html、index.css、index....
  • 内存分配的概念

    千次阅读 2018-03-08 11:35:05
    我们写过很多c/c++代码(或者其他编程语言),然后通过编译器进行编译再运行一个程序,要使用数据对象(例如变量、类对象)是得要分配内存的,而大家可能不太熟悉这些数据对象是如何分配的。那么接下来,笔者为大家...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 86,356
精华内容 34,542
关键字:

内存分配图怎么画