内存碎片

C++面试题

时光怂恿深爱的人放手 提交于 2020-03-08 08:06:32
语言基础类 1. 指针和引用的区别? (1)指针有自己的一块空间,而引用只是一个别名;  (2)使用 sizeof 看一个指针的大小为 4 字节(32位,如果要是64位的话指针为8字节),而引用则是被引用对象的大小。 (3) 引用必须在定义时被初始化,指针不必; (4)不存在指向空值的引用,但存在指向空值的指针。 2.static和 const的用法,(能说出越多越好)(重点) 首先说说const的用法(绝对不能说是常数) 1.限定变量为不可修改。 2.限定成员函数不可以修改任何数据成员。 3.使用const关键字修饰的变量,一定要对变量进行初始化 下面的声明都是什么意思? const int a; a是一个常整型数 int const a; a是一个常整型数 const int *a; a是一个指向常整型数的指针,整型数是不可修改的,但指针可以 int * const a; a为指向整型数的常指针,指针指向的整型数可以修改,但指针是不可修改的 int const * a const; a是一个指向常整型数的常指针,指针指向的整型数是不可修改的,同时指针也是不可修改的 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

JAVA垃圾回收机制

痴心易碎 提交于 2020-03-07 22:23:18
一、概述 Java语言的特点就是将对象的管理权交给了内存管理机制,在jvm的自动内存管理机制下,不需要为每一个对象去写delete或者free代码,不容易出现内存泄漏或内存溢出的问题。但正因为java程序员将内存管理权力交给了内存管理机制,所以一旦出现内存泄漏或者内存溢出的问题,在对jvm内存结构不清楚的情况下,排查错误将会成为一项非常复杂且困难的工作。 二、运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。 2.1、程序计数器 线程私有; 可以看作是当前线程所执行的字节码的行号指示器; 程序计数器是唯一不发生任何OutOfMemoryError的区域。 2.2、Java虚拟机栈 线程私有; 每个方法被执行的时候,虚拟机会创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息,每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程; 局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配的局部变量空间时完全确定的。 2.3、本地方法栈 与虚拟机栈所发挥的作用是非常相似的,其区别是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈是为虚拟机使用到的本地方法服务; Java方法是由Java语言编写,编译字节码,存储在class文件中,与平台无关,本地方法是由其他语言

生产要不要开启MySQL查询缓存

一笑奈何 提交于 2020-03-07 18:51:54
一、前言 在当今的各种系统中,缓存是对系统性能优化的重要手段。MySQL Query Cache(MySQL查询缓存)在MySQL Server中是默认打开的,但是网上各种资料以及有经验的DBA都建议生产环境中把MySQL Query Cache关闭。按道理,MySQL Server默认打开,是鼓励用户使用缓存,但是大拿们却建议关闭此功能,并且国内各个云厂商提供的MySQL云服务中默认都是关闭这个功能,这是为什么?他们在使用中遇到了什么坑?本文将会从以下几方面来详解MySQL Query Cache。 1.MySQL查询缓存是什么? MySQL缓存规则是什么? 如何配置和缓存MySQL缓存 MySQL缓存的优缺点 生产要不要开启MySQL缓存 二、 MySQL查询缓存简介 MySQL查询缓存是MySQL中比较独特的一个缓存区域,用来缓存特定Query的整个结果集信息,且共享给所有客户端。为了提高完全相同的Query语句的响应速度,MySQL Server会对查询语句进行Hash计算后,把得到的hash值与Query查询的结果集对应存放在Query Cache中。当MySQL Server打开Query Cache之后,MySQL Server会对接收到的每一个SELECT 语句通过特定的Hash算法计算该Query的Hash值,然后通过该hashi值到Query Cache中去匹配

《面试必问之jvm与性能优化》(二)

烂漫一生 提交于 2020-03-07 17:16:12
1. 说说各个区域的作用? 1、运行时数据区域 运行时数据区域包括方法区、虚拟机栈、本地方法栈、堆、程序计数器。其中方法区和堆是所有线程共享的数据区,其他的是线程隔离的数据区。 1.1、程序计数器 程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器,确定下一条需要执行的字节码指令。java的多线程是通 过线程轮流切换并分配处理器执行时间的方式来实现的,在任何确定的一个时刻,一个处理器只会执行一条线程中的指令。为了线程切换之后能恢复到正确的执行位 置,每个线程都需要有一个独立的程序计数器,各个线程之间的计数器互不影响。如果线程正在执行的是一个java方法,则计数器记录的是正在执行的虚拟机字 节码指令的地址,如果正在执行的是native方法,则计数器值为空。 1.2、java虚拟机栈 java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是java方法执行的内存模型:每个方法被执行的时候都会创建一个栈帧用 于存在局部变量表、操作栈、动态链接、方法出口等信息。通过所说的栈是局部变量表,即与对象内存分配关系最密切的内存区域。局部变量表的内存空间在编译期 间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是确定的,在运行期不会改变。 java虚拟机栈有两种异常:如果线程请求的栈深度大于虚拟机所允许的深度

JVM深入解析

有些话、适合烂在心里 提交于 2020-03-07 14:37:23
Java运行时数据区: Java虚拟机在执行Java程序的过程中会将其管理的内存划分为若干个不同的数据区域,这些区域有各自的用途、创建和销毁的时间,有些区域随虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束来建立和销毁。Java虚拟机所管理的内存包括以下几个运行时数据区域,如图: 1、程序计数器:指向当前线程正在执行的字节码指令。线程私有的。 2、虚拟机栈:虚拟机栈是Java执行方法的内存模型。每个方法被执行的时候,都会创建一个栈帧,把栈帧压人栈,当方法正常返回或者抛出未捕获的异常时,栈帧就会出栈。 (1)栈帧:栈帧存储方法的相关信息,包含局部变量数表、返回值、操作数栈、动态链接 a、局部变量表:包含了方法执行过程中的所有变量。局部变量数组所需要的空间在编译期间完成分配,在方法运行期间不会改变局部变量数组的大小。 b、返回值:如果有返回值的话,压入调用者栈帧中的操作数栈中,并且把PC的值指向 方法调用指令 后面的一条指令地址。 c、操作数栈:操作变量的内存模型。操作数栈的最大深度在编译的时候已经确定(写入方法区code属性的max_stacks项中)。操作数栈的的元素可以是任意Java类型,包括long和double,32位数据占用栈空间为1,64位数据占用2。方法刚开始执行的时候,栈是空的,当方法执行过程中,各种字节码指令往栈中存取数据。 d、动态链接

C语言--疑问解析

别来无恙 提交于 2020-03-07 14:28:16
1.局部变量未初始化值不确定,全局变量初始值为0;(vs2017局部变量不初始化报错) 2.大小端模式问题: 大端模式:高位数据存储在低地址内存单元,数据的低位数保存在高地址内存单元中。即地址由低到高,而数据字节位数由高到低。 小端模式:数据的低位字节保存在高地址内存单元,数据的高字节保存在低地址内存单元中。即地址由低到高,数据字节位数由高到低。 假设变量x的类型为int,位于地址Ox:100,其值为Ox01234567,其地址范围为Ox100~Ox103,其内部数据排列顺序由机器类型决定。 大端模式:Ox100 01, Ox101 23,Ox102 45,Ox103 67 小端模式:Ox100 67, Ox101 45, Ox102 23, Ox103 01 3.# include <string.h> void *memset(void *s, int c, unsigned long n); 函数的功能是:将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,注意 c 是 int 型。s 是 void* 型的指针变量,所以它可以为任何类型的数据进行初始化。memset() 的作用是在一段内存块中填充某个给定的值。因为它只能填充一个值,所以该函数的初始化为原始初始化,无法将变量初始化为程序中需要的数据。用memset初始化完后

Linux内存管理专题

北城以北 提交于 2020-03-07 14:15:08
专题: Linux内存管理专题 关键词: malloc、brk、VMA、VM_LOCK、normal page、special page 。 每章问答: malloc()函数是C函数库封装的一个核心函数,对应的系统调用是brk()。 1. brk实现 要了解brk的实现首先需要知道进程用户空间的划分,以及struct mm_struct结构体中代码段、数据段、堆相关参数。 然后brk也是基于VMA,找到合适的虚拟地址空间,创建新的VMA并插入VMA红黑树和链表中。 首先看看mm_struct中代码段、数据段相关参数,和 Linux内存管理框架图 结合看。 由于栈向低地址空间增长,堆向高地址空间增长,所以栈的起始地址start_stack和堆的结束地址brk会改变。在栈和堆之间是 struct mm_struct { ... unsigned long start_code, end_code, start_data, end_data;-----代码段从start_code到end_code;数据段从start_code到end_code。 unsigned long start_brk, brk, start_stack;--------------------堆从start_brk开始,brk表示堆的结束地址;栈从start_stack开始。 unsigned long arg

Linux内存分配机制

不羁岁月 提交于 2020-03-07 14:07:34
原文:https://blog.csdn.net/gfgdsg/article/details/42709943 Linux 的虚拟内存管理有几个关键概念: 1、每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址; 2、虚拟地址可通过每个进程上的页表(在每个进程的内核虚拟地址空间)与物理地址进行映射,获得真正物理地址; 3、如果虚拟地址对应物理地址不在物理内存中,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。 基于以上认识,进行了如下分析: 一、Linux 虚拟地址空间如何分布? Linux 使用虚拟地址空间,大大增加了进程的寻址空间,由低地址到高地址分别为: 1、只读段:该部分空间只能读,不可写;(包括:代码段、rodata 段(C常量字符串和#define定义的常量) ) 2、数据段:保存全局变量、静态变量的空间; 3、堆 :就是平时所说的动态内存, malloc/new 大部分都来源于此。其中堆顶的位置可通过函数 brk 和 sbrk 进行动态调整。 4、文件映射区域 :如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间。 5、栈:用于维护函数调用的上下文空间,一般为 8M ,可通过 ulimit –s 查看。 6、内核虚拟空间

JVM垃圾回收

时间秒杀一切 提交于 2020-03-07 11:16:17
一.简介 最近又复习下jvm相关内容,理解下思想,吸收下前辈经验,本文jdk 1.7/1.8 二.引用计数法与可达性分析 垃圾回收,便是将已经分配出去的的,但却不再使用的内存回收回来,以便能够再次分配。在Java虚拟机的语境下,垃圾指的是死亡对象所占据的堆空间。这里便涉及了一个关键问题:如何辨别一个对象死亡。 2.1 引用计数法 给个对象添加引用计数器,每当有一个地方引用它,计数器值就加1;当引用失效时,计数器值就减一;任何时刻计数器为0的对象就是不再被使用。 引用计数法有个重大的漏洞,无法处理循环引用的对象。 public class ReferenceCountingGC { public Object instance = null; private static final int _1MB = 1024*1024; //占内存 private byte[] bigSize = new byte[2 *_1MB]; public static void testGC(){ ReferenceCountingGC objA = new ReferenceCountingGC(); ReferenceCountingGC objB = new ReferenceCountingGC(); objA.instance = objB; objB.instance = objA;

golang runtime 简析

不打扰是莪最后的温柔 提交于 2020-03-07 05:22:54
Go Runtime 的总览 golang 的 runtime 在 golang 中的地位类似于 Java 的虚拟机,不过 go runtime 不是虚拟机. golang 程序生成可执行文件在指定平台上即可运行,效率很高, 它和 c/c++ 一样编译出来的是二进制可执行文件. 我们知道运行 golang 的程序并不需要主机安装有类似 Java 虚拟机之类的东西,那是因为在编译时,golang 会将 runtime 部分代码链接进去. golang 的 runtime 核心功能包括以下内容: 协程(goroutine)调度(并发调度模型) 垃圾回收(GC) 内存分配 使得 golang 可以支持如 pprof、trace、race 的检测 支持 golang 的内置类型 channel、map、slice、string等的实现 等等 下图 1 是 golang 程序、runtime、可执行文件与操作系统之间的关系. 区别于 Java 需要安装虚拟机,go 语言的可执行文件已经包含了 golang 的 runtime,它为用户的 go 程序提供协程调度、内存分配、垃圾回收等功能.此外还会与系统内核进行交互,从而真正的利用好 CPU 等资源. 本文主要简单介绍 golang runtime 的并发调度模型、垃圾回收与内存分配. 协程调度模型 调度是操作系统的核心功能了,从计算机诞生以来