内存碎片

《Glibc内存管理》笔记DAY2

a 夏天 提交于 2019-12-19 04:22:33
目录 Ptmalloc内存管理设计 Main_arena 与 non_main_arena chunk 的组织 空闲 chunk 容器 sbrk 与 mmap 内存分配概述 内存回收概述 边界标记法 内容来源 Ptmalloc内存管理设计 具有长生命周期的大内存分配使用 mmap。 特别大的内存分配总是使用 mmap。 具有短生命周期的内存分配使用 brk,因为用 mmap 映射匿名页,当发生缺页异常时,linux 内核为缺页分配一个新物理页,并将该物理页清 0,一个 mmap 的内存块需要映射多个物理页,导致多次清 0 操作,很浪费系统资源,所以引入了 mmap分配阈值动态调整机制,保证在必要的情况下才使用 mmap 分配内存。 尽量只缓存临时使用的空闲小内存块,对大内存块或是长生命周期的大内存块在释放时都直接归还给操作系统。 对空闲的小内存块只会在 malloc 和 free 的时候进行合并,free 时空闲内存块可能放入 pool 中,不一定归还给操作系统。 收缩堆的条件是当前 free 的块大小加上前后能合并 chunk 的大小大于 64KB,并且堆顶的大小达到阈值,才有可能收缩堆,把堆最顶端的空闲内存返回给操作系统。 需要保持长期存储的程序不适合用 ptmalloc 来管理内存。 为了支持多线程,多个线程可以从同一个分配区(arena)中分配内存,ptmalloc假设线程

jvm内存模型概述

北城余情 提交于 2019-12-18 12:33:24
一、Jvm 的介绍 1、JVM体系结构 2、JVM运行时数据区 3、JVM内存模型 JVM运行时内存 = 共享内存区 + 线程内存区 3.1、共享内存区 共享内存区 = 持久带(方法区 + 其他)+ 堆(Old Space + Young Space(den + S0 + S1)) 持久代 : JVM用持久带(Permanent Space)实现方法区,主要存放所有已加载的类信息,方法信息,常量池等等。可通过-XX:PermSize和-XX:MaxPermSize来指定持久带初始化值和最大值。 Permanent Space并不等同于方法区,只不过是Hotspot JVM用Permanent Space来实现方法区而已 ,有些虚拟机没有Permanent Space而用其他机制来实现方法区。 堆(heap) : 主要用来存放类的对象实例信息(包括new操作实例化的对象和定义的数组)。 堆分为Old Space(又名,Tenured Generation)和Young Space。Old Space主要存放应用程序中生命周期长的存活对象;Eden(伊甸园)主要存放新生的对象;S0和S1是两个大小相同的内存区域,主要存放每次垃圾回收后Eden存活的对象,作为对象从Eden过渡到Old Space的缓冲地带(S是指英文单词Survivor Space)。堆之所以要划分区间

分段和分页的区别

南笙酒味 提交于 2019-12-18 11:35:02
连续分配方式会形成许多碎片,从而采用离散分配方式。采用页为分配的基本单位,可以避免产碎片,只在最后一页可能产生内碎片。若采用段为基本单位,则称之为分段存储管理方式,段可通俗理解为大的页面,段内采用连续分配,段与段之间采用离散分配。 基本分页存储管理方式 页面 : 分页存储管理是将一个进程的逻辑地址空间分成若干大小相等的片,称之为页。并给各个页加以编号,从0开始。相应的,内存也分成与页面等大的若干存储块,称为物理块戍页框,同样为它们加以编号。在为进程分配内存时,以块为单位将进程的若干页分别装入到多个可以不相邻的物理块中。由于进程的最后一页通常装不满而形成不可利用的碎片,称之为“页内碎片“。页面大小一般为2的幂。 页面地址结构 : 分页地址由项号,偏移量(页内地址)组成。 页表:系统要为每一个进程都建立一个页表。在进程地址空间内的所有页,依此在页表中有一项表项,记录了相应页在内存中的对应的物理块号。页表是实现从页号到物理块号的地址映射。 地址变换机构 : 该机构是实现从逻辑地址到物理地址的转换,页内地址和物理地址是一一对应的,地址变换机构的任务是将逻辑地址中的页号,转换为内存中的物理块号。借助页表实现。 基本的地址变换机构 : 如果页号大于或等于页表长度,表示本次所访问的地址超过进程的地止空间,若未越界,则将页表地止与页号和页表项长度的乘积相加(即,基地止*偏移量

JVM垃圾回收(三)

强颜欢笑 提交于 2019-12-18 03:09:50
一、对象是生是死 Java堆几乎存放着所有的对象实例,垃圾回收器回收垃圾前,需要判断哪些是存活的哪些是死去的。 引用计数器算法 :给对象添加一个引用计数器,当持有这个对象引用时,则计数器加一;当引用失效时,则计数器减一;当计数器为0的时候表示对象没有任何引用。这种算法不适合Java的垃圾回收器,因为无法解决对象间的互相引用。 可达性算法 :Java定义GC Root,作为引用链(Reference Chain)的依据,并指定哪些可作为GC Root如 java虚拟机栈中的局部变量表引用的对象、方法区的静态变量引用的对象、方法区的常量引用的对象、本地方法栈(Native方法)引用的对象、类加载器、Thread 。但仅仅定义引用和未引用太过于狭隘,因此在jdk1.2以后将引用划分为四种,分别是强引用( 强引用类似Object obj = new Object(),如果obj到GC Root可达则JVM永不会回收这对象 )、软引用(描述一些不是特别重要的对象,在JVM即将发生OOM异常时,对这些对象列入回收范围进行第二次回收,如果还是内存不足则会抛出OOM异常)、弱引用(描述哪些不重要的对象,相比于软引用,这些对象只会存活到下一次垃圾回收之前, eg:Map中存放key/value,如果某个key程序再也用不到,此时使用弱引用后将key=null,这样这个key就会被回收)和虚引用

jvm垃圾回收器与内存分配策略

醉酒当歌 提交于 2019-12-18 00:36:52
一、判断对象存活的算法 1 、引用计数算法 ( 1 )概念:给对象中添加一个引用计数器每当有一个地方引用它时,计数器值加 1 ;当引用失效时,计数器就减 1 ;任何时刻计数器为 0 的对象就是不可能再被使用的。 ( 2 ) java 虚拟机里面没有选用引用计数算法来管理内存,其中最主要的原因是它很难解决对象之间相互循环引用的问题。 2 、可达性分析算法 ( 1 )概念:通过一系列的成为“ GC Roots ”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连(用图论的话来说,就是从 GC Roots 到这个对象不可达)时,则证明此对象是不可用的。 二、finalize 方法 1、进行垃圾回收前可以调用的方法(有没有必要调用)。 2、 可以进行一次自我拯救,在垃圾回收之前关联某一个对象就可以,但是只能一次,因为 finalize 方法只能被系统自动调用一次。 3 、卡大型分析算法中不可达对象,是一个“缓刑”阶段。要真正宣告一个对象死亡,至少要经历两次标记过程。 三、垃圾收集算法 1、 标记 - 清除算法: ( 1 )概念:算法氛围“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。 ( 2 )不足:一是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题

Redis安装和配置

久未见 提交于 2019-12-17 19:57:17
关系型数据库与非关系型数据库 关系型数据库: 一个机构化的数据库,创建在关系模型基础上,一般面向于记录 包括oracle,mysql,sqlserver,db2 非关系型数据库: 除了主流的关系型数据库意外的数据库,都人为是非关系型的 包括redis,mongdb,hbase,couhdb 非关系型数据库产生背景 对数据库高并发读写需求 对海量数据高效存储与访问需求 对数据库高可扩展性与高可用需求 Redis简介 Redis基于内存运行并支持持久化 采用key-value(键值对)的存储形式 优点: 具有极高的数据读写速度 支持丰富的数据类型 支持数据的持久化 原子性 支持数据备份 1,安装必要的环境组件,并安装redis [root@localhost ~]# yum install gcc gcc-c++ make -y ##安装环境组件 [root@localhost ~]# mount.cifs //192.168.100.3/LNMP-C7 /mnt/ ##挂载 Password for root@//192.168.100.3/LNMP-C7: [root@localhost ~]# cd /mnt/ [root@localhost mnt]# tar zxvf redis-5.0.7.tar.gz -C /opt/ ##解压 [root@localhost mnt]#

Java深入剖析之JVM

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

JVM-6-垃圾回收算法

百般思念 提交于 2019-12-17 01:46:37
三如何垃圾回收 GC(Garbage Collection)垃圾回收算法 标记清除 速度快,但是会产生内存碎片; 标记整理 解决了标记清除内存碎片的问题,但是每次都得移动对象,因此成本很高; 复制算法 没有内存碎片也不需要移动对象,但是导致空间的浪费 分代收集算法:在上边三种收集思想中加入了分代的思想。 标记清除(Mark-Sweep) 这种算法分两步:标记、清除两个阶段。 标记阶段是从根集合(GC Root)开始扫描,每到达一个对象就会标记该对象为存活状态, 清除阶段在扫描完成之后将没有标记的对象给清除掉。 这个算法有个缺陷就是会产生内存碎片,如上图B被清除掉后会留下一块内存区域,如果后面需要分配大的对象就会导致没有连续的内存可供使用。 标记整理(Mark-Compact) 标记整理就没有内存碎片的问题了,也是从根集合(GC Root)开始扫描进行标记然后清除无用的对象,清除完成后它会整理内存。 这样内存就是连续的了,但是产生的另外一个问题是:每次都得移动对象,因此成本很高。 复制算法(Copying) 复制算法会将JVM推分成二等分,如果堆设置的是1g,那使用复制算法的时候堆就会有被划分为两块区域各512m。给对象分配内存的时候总是使用其中的一块来分配,分配满了以后,GC就会进行标记,然后将存活的对象移动到另外一块空白的区域,然后清除掉所有没有存活的对象,这样重复的处理

MySQL数据库初识

拥有回忆 提交于 2019-12-16 22:52:51
一 数据库概述 1. 数据库???   什么是数据库呢?   先来看看百度怎么说的 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。 所谓“数据库”系以一定方式储存在一起、能予多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合。   百度的貌似不好理解啊,让我说啊,数据库是存储数据的地方,超哥,你这不是废话么?这位同学,你你你你你说的对,哈哈,存数据的地方是存在哪里呢,存在硬盘上,为什么不是存在内存里面,因为内存无法永久保存。之前我们存数据都是使用的文件,在一个word文档里面写一些羞羞的网址,然后保存,就存储到硬盘上了。有同学就会说了,超哥,我这通过文件不是也将数据保存上了吗?是的,没毛病,但是你想,通过文件来操作数据,效率是不是很低,首先打开关闭就比较慢,其次是我们操作起来也比较麻烦,对不对,如果我想记录一条关于我个人信息的数据,我使用文档来存,是不是很不友好,并且我们要查数据的时候,看图1:图1是一个word里面记录的信息,如果我想查询出所有人的名字,这个操作是不是就很难搞定了,来来来,配合起来~~,你应该说是的,那我就接着说,有同学可能就会说了,老师我用excel啊,看图2,一列就搞定了,没毛病,但是你想打开操作excel效率低不低。并且通过你自己写的程序来操作这些文件是不是很麻烦

直击面试,聊聊 GC 机制

☆樱花仙子☆ 提交于 2019-12-16 22:49:50
前言 文章来源: https://studyidea.cn/ GC 中文直译垃圾回收,是一种回收内存空间避免内存泄漏的机制。当 JVM 内存紧张,通过执行 GC 有效回收内存,转而分配给新对象从而实现内存的再利用。 JVM GC 机制虽然无需开发主动参与,减轻不少工作量,但是某些情况下,自动 GC 将会导致系统性能下降,响应变慢,所以这就需要我们提前了解掌握 GC 机制。当面对这种情况时,才能从容不迫的解决问题。另外 GC 机制也是 Java 面试高频考题,了解掌握 GC 是一项必备技能。 学习 GC ,首先我们解决三个问题: 什么是垃圾 在哪里回收垃圾 怎么回收垃圾 什么是垃圾 我们先来看一段简单的代码。 上面代码通过将字符串对象转化成字节数组,然后写入本地文件。方法一旦开始执行,就将会在分配一定内存给新建的对象,然后将引用告诉了 str , bytes 变量。等到方法执行完毕,方法内部局部变量紧接将就会被销毁。但是这样仅仅销毁了局部变量,却没有带走内存上这些实际的对象。这类不再起作用,没有被引用的对象,将其归类为垃圾。 在偌大的内存上存活着无数对象, GC 之前需要准确将这些对象标记出来,分为存活对象与垃圾对象。这个过程一旦少标记,那就只能等待下次 GC 标记,再回收,这样将会影响 GC 效率。另外决不能错标记,将正常存活对象标记为垃圾。一旦回收正常存活的对象