前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >27-内存知识

27-内存知识

作者头像
zx钟
发布2021-07-06 09:40:15
3620
发布2021-07-06 09:40:15
举报
文章被收录于专栏:测试游记测试游记

基础概念

内存又叫主存,是CPU与其他设备沟通的桥梁,主要用来临时存放数据,配合CPU工作,协调CPU的处理速度

  • 硬盘数据,外设数据,玩了传输数据,要进CPU前,都要先进入内存
  • 临时存放,在断电后,内存内容就会丢失

内存的组成:内存地址+存储单元

存储单元-数据结构

堆栈

两种不同的数据结构

堆(heap)

一种经过排序的树型数据结构

存放程序的对象

链表

数组、列表:数据是有顺序的,从左到右,从0开始。如果要在列表中,插入一个数据,那么在插入位置之后的数据,都需要移动,删除列表中间某个数据,在位置之后的数据,也都要移动。

链表也是一种数组,它的每个数据存储的都是数据值+下一个元素的地址。

如果要在链表中,插入一个数据。插入位置「前一个元素」中的「下一个元素的地址」需要指向插入的数据的地址,「待插入的元素」记录「下一个元素的地址」。

查找一个数据时,需要从头开始读取数据,一个一个的比对,直到找到需要的数据才停止。这个过程会有大量的IO,所以读取数据速度并不快。

  • 二叉树

建立在链表的基础上的一种数据结构

二叉树左边存储的是小于自身数据,右边是存储大于自身数据

插入数据:因为是链表,插入速度也比较快

读取数据:因为数据已经做了二分,查找链路变短,IO就减少了,读取速度也变快

二叉树的不足:随着存储的数据量增大,二叉树会越来越大,那要查找某个数据的IO次数,也会非常多

  • B树「平衡二叉树」

不是一个简单的平衡二叉树,是一个立体的平衡二叉树

B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个),数据库索引技术里大量使用者B树和B+树的数据结构

LIFO「Last In First Out」后进先出

  • 装入叫压入
  • 取出叫弹出
队列

FIFO「First In First Out」先进先出

  • 顺序队列
  • 循环队列

内存使用

一个程序运行起来,需要分配一块内存空间,无异常时,就在分配的空间中弹性伸缩存储

这个存储空间至少包含一块栈区,一块堆区,还会包括其他

  • 栈区:存放程序中的变量
  • 堆区:存放程序中的对象

JVM java虚拟机

程序计数器、java虚拟机栈、本地方法栈、方法区、堆内存

  • 程序计数器:记录持续执行字节码的行号指示器
  • java虚拟机栈:java方法执行时的内存模型
  • StackOverflowError:线程请求的栈深度大于虚拟机运行的最大深度
  • OutOfMemoryError:栈在动态扩展时,无法申请到足够的内存空间
  • 内存泄漏:程序运行时,申请的内存空间使用完了,不及时释放,导致可申请的内存空间越来越少。可以使用的内存空间越来越少。
  • 方法区:共享内存区域,存储已被虚拟机加载的数据
  • 栈内存:存储局部变量,变量有一定的作用域,离开作用域,空间就会被释放,所以更新速度快,生命周期短
  • 堆内存:存储数组和对象,new出来的都存堆里,如果数据消失,实体不会马上释放

OOM会导致整个内存条空间全被使用吗?不会!只会消耗该程序申请的空间,不会消耗内存条全部空间

堆内存
  • 新生代=Eden(存放JVM刚分配的对象) + Survivor1 + Survivor2 (两个空间一样大,Eden中未被GC的对象,会在这两个区间来回拷贝,默认拷贝超过15次,就移入年老代)
  • Tenured 年老代
  • Perm 永久代(元空间)

内存空间的释放

GC资源回收

需要有GC,但是频率要合理,不能过高

怎么判断是可回收
  • 是否可达
  • 是否存活
判断哪些可被回收
  • 不要的、不能被回收:新生代、年老代
  • 拷贝算法:把新生代变为年老代
什么时候回收
  • 分配的空间不足,才会执行回收
  • 定时回收
怎么回收

垃圾回收算法:新生代-复制算法「清理Eden,将存活的复制到Survivor」,年老代-标记整理算法「先标记,再整理」

资源回收

只有在讲「堆」的时候,才会说资源回收。本地方法栈、程序计数器、虚拟机栈这些是不需要进行垃圾回收的

Java的内存回收机制

内存空间中垃圾回收的工作由垃圾回收器「Garbage Collecot,GC」完成。它的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。

参数含义

-Xms:初始堆大小 -Xmx:最大堆空间 -Xmn:设置新生代大小 -XX:SurivivorRatio:新生代eden空间,from空间,to空间的比例关系 -XX:PermSize:方法区初始大小 -XX:MaxPermSize:方法区最大值 -XX:MetaspaceSize:元空间GC阈值 -XX:MaxMetaspaceSize:最大元空间大小 -Xss:栈大小 -XX:MaxDirectMemorySize:直接内存大小,默认为最大堆空间

查看内存

代码语言:javascript
复制
root@zx:~# free -h
              total        used        free      shared  buff/cache   available
Mem:          3.8Gi       414Mi       293Mi       2.0Mi       3.2Gi       3.2Gi
Swap:            0B          0B          0B

Mem:物理内存

  • total合计
  • used已被用
  • free未使用
  • shared共享
  • buff/cache缓冲区、缓存
  • buff:对原始磁盘块(操作系统与磁盘交流的最小单位)的临时存储
  • cache:从磁盘读取文件的页缓存
  • available新进程可分配=free+可回收的

Swap:交换分区

一种虚拟内存,由磁盘虚拟化而来,存在于内存和磁盘之间,因为磁盘和内存之间速度存在差异

代码语言:javascript
复制
top - 14:51:35 up 169 days,  4:55,  1 user,  load average: 0.01, 0.02, 0.00
Tasks: 108 total,   1 running, 107 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.2 us,  0.5 sy,  0.0 ni, 98.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3936.1 total,    294.0 free,    414.6 used,   3227.6 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   3266.4 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                     
 479183 root      10 -10  128.7m  37.5m  14.5m S   2.3   1.0 487:05.64 AliYunDun                                                   
 672280 root      20   0   59.3m  53.2m   5.9m S   1.0   1.4 139:43.55 gunicorn                                                    
 479138 root      10 -10   21.8m   5.7m   4.9m S   0.3   0.1  27:41.60 AliYunDunUpdate

VIRT 虚拟内存使用量 = Swap + RES

RES 物理内存使用量+未换出的虚拟内存大小 = CODE + DATA

SHR 共享内存使用量

Swap 虚拟内存中被换出的大小

CODE 代码占用的物理内存大小

DATA 代码之外的部分占用的物理内存大小

%MEM 使用的物理内存占总内存的比率

内存分析

jmap

命令:jmap [options] pid

-dump:生成java堆栈的快照信息 -heap:显示java堆详细信息,使用那种回收机制,参数配置,分代情况 -histo:显示堆中对象统计信息,包括类,实例数量

代码语言:javascript
复制
jmap -F -dump:format=b,file=jvmpertest110901.bin 3636
format=b 格式为二进制
file 输出到什么文件,文件格式.bin
3636 进程pid

这个命令,执行时间很长,生成的文件也很大

arthas

阿里巴巴开源的java诊断工具,实现了jvm自带的几乎所有诊断功能

安装
代码语言:javascript
复制
curl -O https://arthas.aliyun.com/arthas-boot.jar
工具上手
代码语言:javascript
复制
java -jar arthas-boot.jar
内存泄漏抓包
  • dashboard
  • heapdump

jvm分析

输出gc日志

jvm的启动参数中加入

代码语言:javascript
复制
-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplicationsStopedTime

启动后输出:GC概要信息,详细信息,gc时间,gc造成的应用暂停时间

jcosole

jdk自带的内存分析工具,有图形界面,可以查看jvm内存信息,线程信息,类加载信息,MBean信息

代码语言:javascript
复制
jconsole.sh pid

jstat

jdk自带的分析gc工具,参数很多

代码语言:javascript
复制
jstat -gcutil pid 10000 间隔10000毫秒显示一次gc信息
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基础概念
  • 存储单元-数据结构
    • 堆栈
      • 堆(heap)
        • 链表
        • 队列
      • 内存使用
        • JVM java虚拟机
          • 堆内存
        • 内存空间的释放
          • 怎么判断是可回收
          • 判断哪些可被回收
          • 什么时候回收
          • 怎么回收
        • 资源回收
          • Java的内存回收机制
          • 参数含义
          • 查看内存
          • 内存分析
            • jmap
              • arthas
                • 安装
                • 工具上手
                • 内存泄漏抓包
            • jvm分析
              • 输出gc日志
                • jcosole
                  • jstat
                  相关产品与服务
                  弹性伸缩
                  弹性伸缩(Auto Scaling,AS)为您提供高效管理计算资源的策略。您可设定时间周期性地执行管理策略或创建实时监控策略,来管理 CVM 实例数量,并完成对实例的环境部署,保证业务平稳顺利运行。在需求高峰时,弹性伸缩自动增加 CVM 实例数量,以保证性能不受影响;当需求较低时,则会减少 CVM 实例数量以降低成本。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档