精华内容
下载资源
问答
  • 内存布局

    2020-12-08 16:39:42
    内存是硬盘和cpu的中间桥梁,jvm内存布局规定了java在过程中内存申请、分配、管理的策略 内存布局如下图 Heep(堆) Heep是OOM故障最主要的发源地,他存储的几乎多有的实例对象。 Heep内是由垃圾收集器自动回收...

    概述:

    内存是硬盘和cpu的中间桥梁,jvm内存布局规定了java在过程中内存申请、分配、管理的策略

    内存布局如下图

    Heep(堆)

    Heep是OOM故障最主要的发源地,他存储的几乎多有的实例对象。

    Heep内是由垃圾收集器自动回收的。

    启动时设置堆内存的初始值参数: -Xms... (最小堆内存)  -Xmx...(最大堆内存)

    在运行期间,堆空间不断的扩容和收缩,所以设置初始值时,Xms和Xmx设置成一样大小,避免GC

    后调整堆大小带来的不必要的系统压力

     

    堆内存分为两大块,新生代有分为Eden s0 s1

    对象新创建时在新生代,步入暮年进入老年代,

    如果新创建的对象新生代无法容纳, 会将其直接放到老生代

    当Eden区装满的时候会触发 YGC(Yong Garbage Collection)策略

    执行策略的时候,没有被引用的直接被回收。依然存活的的对象移送到survivor,

    每次移送的的时候都是将存活的对象复制到s0或s1中未使用的那块空间,然后把另一块空间完全清除。

    如果移送的对象大于survivor的容量,则直接交给老年代。

    一个对象如果在Survivor交换的次数达到 --XX:MaxTenuringThreshold配置的值,则直接移至老年代, 默认为15

    请结合下图进行查看

     

    Metaspace(元空间)

    在JDK7之前Hotspot存在perm区(永代区), 作为元空间的前身。

    但是Perm区有很大的问题,他在启动时固定大小,很难调优, 并且在FGC的时候会移动类元信息。

    如果动态类加载过多,容易引发Perm区的OOM, 解决此问题,需要设置启动参数 -XX:MaxPermSize=1280m.

    但是部署到新机器上,可能会因为没有修改JVM参数导致故障在现

    基于以上jdk8将Perm用元空间取代

    jdk8中Perm中所有内容字符串常量移至堆内存,其他内容包括类元信息、字段、静态属性、方法、常量等都移动至元空间

     

    JVM Stack(虚拟机栈)

    栈是一个先进后出的数据结构 。

    JVM中的虚拟机栈是描述java方法执行的内存区域,是线程私有的;

    如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;

    如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常

    详细解释请看这篇文章

     

    Native Method Stacks(本地方法栈)

    在JVM中是线程私用的;

    服务于Native方法;

    线程调用本地方法时,则不在受JVM约束;

    本地方法可以通过JNI(Java Native Interface) 来访问虚拟机运行时的数据去,甚至可以调用寄存器。

    Program Counter Register程序计数寄存器

    请看这篇文档了解Program Counter Register

     

    展开全文
  • 文章目录进程空间内存布局内存布局编程代码 进程空间内存布局 不管学习c语言还是学习linux下的编程,我们都要了解并学习。每个进程先天就有0-4G的各自互不干涉的虚拟内存空间,0-3G是用户空间执行用户自己的代码,高...

    进程空间内存布局

    不管学习c语言还是学习linux下的编程,我们都要了解并学习。每个进程先天就有0-4G的各自互不干涉的虚拟内存空间,0-3G是用户空间执行用户自己的代码,高1GB的空间是内核空间执行linux系统调用。这里存放着整个内核的代码和所有的内核模块,用户所看到和接触的都是该虚拟地址,并不是实际的物理地址。linux下一个进程在内存里有三部分的数据,就是“代码段”、“堆栈段”和“数据段”。
    下面我们来看一下linux下进程的内存布局
    在这里插入图片描述

    上述图片文字解析

    1、栈(Stack):栈内存由编译器在程序编译阶段完成,进程的栈空间位于进程用户空间的顶部并且是向下增长,每个函数的每次调用都会在栈空间中开辟自己的栈空间,函数参数、局部变量、函数返回地址等都会按照先入者为栈顶的顺序压入函数栈中,函数返回后该函数的栈空间消失,所以函数中返回局部变量的地址都是非法的。

    2、堆(Heap):堆内存是在程序执行过程中分配的,用于存放进程运行中被动态分配的的变量,大小并不固定,堆位于非初始化数据段和栈之间,并且使用过程中是向栈空间靠近的。当进程调用 malloc 等函数分配内存时,新分配的内存并不是该函数的栈帧中,而是被动态添加到堆上,此时堆就向高地址扩张;当利用free 等函数释放内存时,被释放的内存从堆中被踢出,堆就会缩减。因为动态分配的内存并不在函数栈帧中,所以即使函数返回这段内存也是不会消失。

    3、未初始化数据段(.bss):用来存放未初始化的全局变量和 static 静态变量。并且在程序开始执行之前,就是在 main()之前,内核会将此段中的数据初始化为 0 或空指针。

    4、已初始化数据段(.data): 通常将已初始化数据是在程序中声明,并且具有初值的变量,这些变量需要占用存储器的空间,在程序执行时它们需要位于可读写的内存区域内,并具有初值,以供程序运行时读写。一般用来已初始化的全局变量和 static 静态变量。

    5、文本段也称代码段:这是可执行文件中由 CPU 执行的机器指令部分。正文段常常是只读的,以防止程序由于意外而修改其自身的执行。

    内存布局编程代码

    接下来我们编写并运行下面C程序,验证一下C程序编译以及运行时的进程内存布局:
    我是用linux下vim下写的编程!

    #include <stdio.h>
    #include <stdlib.h>
    
    int g_var1; //g_var1是为未初始化的全局变量,存放在数据段的BSS区,其值默认为0;
    
    int g_var2; //g_var2是初始化了的全局变量,存放在数据段的DATA区,其值为初始化值20
    
    int main(int argc, char **argv)
    {
        static int s_var1;//s_var1是未初始化的静态变量 ,存放在数据段的BSS区,其默认值为0
    
        static int s_var2=10;//s_var2是初始化的静态变量,存放在数据段的DATA区,其值为初始化值10
    
        char   *str="hello";//str是初始化了的局部变量,存放在栈(STACK)中,其值是"Hello"这个字符串常量存放在DATA段里RODATA区中的地址
    
        char   *ptr; //ptr是未初始化了的局部变量,存放在栈中,其值为随机值,这时候的ptr称为“野指针(为初始化的指针)"
    
        ptr = malloc(100); // malloc()会从堆(HEAP)中分配100个字节的内存空间,并将该内存空间的首地址返回给ptr存放;
    
    
        printf("[cmd args]: argv address: %p\n", argv);
        printf("\n");
        printf("[ Stack]: str address: %p\n", &str);
        printf("[ Stack]: ptr address: %p\n", &ptr);
        printf("\n");
        printf("[ Heap ]: malloc address: %p\n", ptr);
        printf("\n");
        printf("[ bss ]: s_var1 address: %p value: %d\n", &s_var1, g_var1);
        printf("[ bss ]: g_var1 address: %p value: %d\n", &g_var1, g_var1);
        printf("[ data ]: g_var2 address: %p value: %d\n", &g_var2, g_var2);
        printf("[ data ]: s_var2 address: %p value: %d\n", &s_var2, s_var2);
        printf("[rodata]: \"%s\" address: %p \n", str, str);
        printf("\n");
        printf("[ text ]: main() address: %p\n", main);
        printf("\n");
        
        return 0;
    }
    

    代码运行结果
    在这里插入图片描述
    结果分析:通过上面代码的地址,我们可以发现,在内存中,从低地址向高地址,依次是文本段、文字常量段、已初始化数据段、未初始化数据段、堆区域和栈区域。(对照上面内存布局图片看)

    展开全文
  • 程序的 内存布局

    2017-02-11 19:58:43
    内存布局

    .out文件,可执行程序的布局:
    这里写图片描述

    文件的布局 和 进程的地址布局 的比较:
    这里写图片描述

    栈和堆要等到程序运行时,由系统来分配空间。

    各个段的作用:

    • 堆栈段在程序运行后才正式存在,是程序运行的基础,main函数也用到栈,因此堆栈要先建立。
    • .bss段存放的是未初始化的全局变量和静态变量。把未初始化的放在一起,清0比较方便。
    • .text段存放的是程序中的可执行代码。
    • .data段保存的是那些已经初始化了的全局变量和静态变量,值要写到内存里。
    • .rodata段存放程序中的常量值,只读数据段,如字符串常量。因此指向字符串常量的指针,不能通过该指针修改字符串的内容。

    静态存储区就是 .bss段 和 .data段
    只读区通常指程序中的.rodata段
    局部变量所占空间为栈空间
    动态内存空间为堆中的空间
    程序可执行代码存放于.text段

    函数的地址对应程序的代码段.text段。函数体的代码位于代码段,运行代码段的过程中,函数中的局部变量在栈空间中,通过指针来读出变量,供代码使用。

    展开全文
  • BIOS内存布局

    2017-12-19 17:25:24
    BIOS内存布局图.C语言九阳神功----内存布局图!学习C语言最重要的莫过于了解内存分布,只有研究到底层去,才能更好的学习C!
  • c++内存布局

    2019-10-03 20:20:48
    有一点值得注意,C语言和C++的内存布局是不一样的,这也就是平日里搜索c++内存布局的文章内容总是很相似但还不相同的原因,有些人没有对比清楚两者区别!我以前也是这样的。 C内存布局 c语...

    写好了代码只是第一步,接下来还需要编译生成对应的二进制才能使用(预处理,编译,汇编,链接)。

    那么在运行的时候,代码和数据在内存中都是怎么分布的呢?c的内存布局是怎样的呢?c++的内存布局是怎样的呢?

    有一点值得注意,C语言和C++的内存布局是不一样的,这也就是平日里搜索c++内存布局的文章内容总是很相似但还不相同的原因,有些人没有对比清楚两者区别!我以前也是这样的。

    C内存布局  

    c语言内存布局分为5部分:初始化数据段,未初始化数据段,代码段、堆区和栈区

    • 初始化数据段分为只读数据和读写数据。
      • 只读数据如初始化的被const修饰的变量或者一些常量,比如`char *str = "abc";`,常量"abc"就存储在只读寄存器中。如果定义成`char str[] = "abc"`,代表的是一个数组,可能定义在栈上,也可能定义在初始化数据段的读写数据中,主要看定义的位置。
      • 读写数据存储被定义了初始值的一些变量,包括初始化过的全局变量和被static修饰的静态变量
    • 未初始化数据段存储未被初始化的变量,也称之为BSS段,即Block Started by Symbol。未被初始化的变量被默认初始化为0,包括全局变量和被static修饰的静态变量
    • 代码段存储代码编译出来的二进制,程序执行的时候由依次执行
    • 堆区存储程序中动态申请出来的空间(malloc出来的,注意free释放内存,否则会出现内存泄漏问题)
    • 栈区存储程序中的局部变量。堆与栈的生长方向相反:栈在内存中也是一种数据结构中栈的样子,是向地址小的方向生长,在linux中可以查看栈的大小`ulimit -s`;堆在内存中的结构如同数据结构中的堆,向着方向大的地方生长,堆比较大,比较接近计算机内存的大小。

     

    C++内存布局  

    C++的内存布局同样分为5个部分:

    • 常量存储区:存储常量字符串,如同C语言内存布局中的初始化数据段的只读数据。
    • 全局变量/静态存储区:如同名字,存储这两类数据,不再区分是否初始化,更加直观容易理解了。包括全局变量,静态变量和常量
    • 代码段:同C语言中代码段
    • 堆区:因为在c++中多了new这个操作符,在堆区中也区分为new的堆区和malloc的堆区。new出来的空间在程序退出时候,操作系统帮忙清理。
    • 栈区:同C语言中栈区

     

    由内存布局的差异而引发出来的问题

    1. 静态变量的问题
      1. 静态变量只在当前文件中生效,其他文件中是看不见的。如果想要在文件中看到另一个文件中的变量,需要使用extern关键字进行修饰,表示该变量已经在其他文件中声明了,此处只是声明一下区通过编译,在link阶段会找到定义的位置进行链接。
      2. 静态局部变量和静态变量,通过static修饰的变量会扩大变量的生命周期,在程序运行的阶段一直存在;而局部变量是存储在栈上的,当当前函数(block)退出后,里面的局部变量就会被退栈释放掉
    2. new和malloc的区别
    3. 堆和栈的区别

    参考文章:

     

    展开全文
  • JVM内存布局

    千次阅读 2019-01-08 00:24:12
    内存布局 Heap(堆) Metaspace(元空间) JVM Stack(虚拟机栈) Native Method Stack(本地方法栈) Program Counter Register(程序计数寄存器) 内存布局 JVM内存布局规定了Java在运行过程中内存申请、...
  • C++ 内存布局

    2021-05-18 18:32:25
    参考 第5篇:C/C++ 内存布局与程序栈
  • 内存布局

    2014-06-19 15:40:49
    C语言九阳神功----内存布局图!学习C语言最重要的莫过于了解内存分布,只有研究到底层去,才能更好的学习C!
  • 进程内存布局 虚拟内存管理
  • 进程内存布局When a C program is created then it is just some pieces of Bytes which is stored in Hard Disk. 创建C程序时,只有一些字节存储在硬盘中。 When a program is double-clicked in windows then ...
  • Linux内存布局

    2020-06-05 20:20:11
    我们先来看下Linux内存布局,此图比我之前写的那篇文章写的布局更详细 在linux中,每一个进程都被抽象为task_struct结构体,称为进程描述符,存储着进程 各方面的信息;例如打开的文件,信号以及内存等等;然后task...
  • 易语言分析数据类型内存布局源码,分析数据类型内存布局,func,ptoint,GlobalSize
  • MTK 内存布局

    2013-04-07 11:33:17
    MTK 平台的内存布局情况和调试,利于用户在MTK 平台上的调试和维护
  • Linux 内存布局

    2019-11-30 14:38:47
    我们先来看下Linux内存布局,此图比我之前写的那篇文章写的布局更详细 在linux中,每一个进程都被抽象为task_struct结构体,称为进程描述符,存储着进程 各方面的信息;例如打开的文件,信号以及内存等等;然后task...
  • 进程内存布局

    2019-10-20 12:13:54
    进程内存布局一. 概述二. 保存时的分段(可执行程序段的分配)三. 分配实例四. 运行后的内存分区五. 进程典型分区 一. 概述 在长期计算机科学的发展中,程序在内存分区已经形成固定的布局。无论是在 Linux/Unix 下的...
  • 切片的内存布局分析
  • 数组定义和内存布局
  • 以下是对C语言中的内存布局进行了详细的分析介绍。需要的朋友可以过来参考下
  • Linux进程内存布局

    2020-02-20 11:59:38
    内存布局图 二.内核空间和用户空间 三.用户空间内存布局 1.栈 2.堆 3.BBS段和Data段 一.内存布局图 二.内核空间和用户空间 虚拟地址的范围是0-4G,内存将这块区域分成两部分,1G的内核空间,供内核使用,...
  • 类对象内存布局

    2021-04-16 10:23:00
    一 虚拟内存布局 1 32位虚拟内存布局 在32位模式下虚拟地址空间总是一个4GB的内存地址块。这些虚拟地址通过页表(page table)映射到物理内存,页表由操作系统维护并被处理器引用。每一个进程拥有一套属于它自己的...
  • 对象内存布局详解

    2021-03-11 16:19:51
    对象内存布局详解 声明 64bit虚拟机和32bit虚拟机,对象所占内存是不一样的: 64位jvm中Mark Word占64bit; 32位jvm中Mark Word占32bit。 根据是否开启元数据类型指针: 如果开启- klass占8字节; 如果不开启...
  • Java对象内存布局

    2021-03-15 21:11:55
    jdk8中,Java对象的内存布局如下图: 其中需注意: (1)数组对象中才有数组长度这一块内存区 (2)所有的对象大小,必须是8字节的整数倍。因此有个内存补齐Padding区,当Java对象的内存不够8字节的整数倍,此...
  • 介绍了C# Struct的内存布局问题解答,有需要的朋友可以参考一下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,303
精华内容 5,721
关键字:

内存布局