关于内存:JVM-内存大对象监控和优化实践

作者:vivo 互联网服务器团队 - Liu Zhen、Ye Wenhao服务器内存问题是影响应用程序性能和稳定性的重要因素之一,须要及时排查和优化。本文介绍了某外围服务内存问题排查与解决过程。首先在JVM与大对象优化上进行了无效的实际,其次在故障转移与大对象监控上提出了牢靠的落地计划。最初,总结了内存优化须要思考的其余问题。 一、问题形容音乐业务中,core服务次要提供歌曲、歌手等元数据与用户资产查问。随着元数据与用户资产查问量的增长,一些JVM内存问题也逐步露出,例如GC频繁、耗时长,在高峰期RPC调用超时等问题,导致业务外围性能受损。 图1 业务异样数量变动 二、剖析与解决通过对日志,机器CPU、内存等监控数据分析发现: YGC均匀每分钟次数12次,峰值为24次,均匀每次的耗时在327毫秒。FGC均匀每10分钟0.08次,峰值1次,均匀耗时30秒。能够看到GC问题较为突出。 在问题期间,机器的CPU并没有显著的变动,然而堆内存呈现较大异样。图2,黄色圆圈处,内存应用急速回升,FGC变的频繁,开释的内存越来越少。 图2 老年代内存应用异样 因而,咱们认为业务性能异样是机器的内存问题导致的,须要对服务的内存做一次专项优化。 步骤1  JVM优化以下是默认的JVM参数: -Xms4096M -Xmx4096M -Xmn1024M -XX:MetaspaceSize=256M -Djava.security.egd=file:/dev/./urandom -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/{runuser}/logs/other如果不指定垃圾收集器,那么JDK 8默认采纳的是Parallel Scavenge(新生代) +Parallel Old(老年代),这种组合在多核CPU上充分利用多线程并行的劣势,进步垃圾回收的效率和吞吐量。然而,因为采纳多线程并行形式,会造成肯定的进展工夫,不适宜对响应工夫要求较高的应用程序。然而,core这类的服务特点是对象数量多,生命周期短。在零碎特点上,吞吐量较低,要求时延低。因而,默认的JVM参数并不适宜core服务。 依据业务的特点和屡次对照试验,抉择了如下参数进行JVM优化(4核8G的机器)。该参数将young区设为原来的1.5倍,缩小了进入老年代的对象数量。将垃圾回收器换成ParNew+CMS,能够缩小YGC的次数,升高进展工夫。此外还开启了CMSScavengeBeforeRemark,在CMS的从新标记阶段进行一次YGC,以缩小从新标记的工夫。 -Xms4096M -Xmx4096M -Xmn1536M -XX:MetaspaceSize=256M -XX:+UseConcMarkSweepGC -XX:+CMSScavengeBeforeRemark -Djava.security.egd=file:/dev/./urandom -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/{runuser}/logs/other 图3 JVM优化前后的堆内存比照 优化后成果如图3,堆内存的应用明显降低,然而Dubbo超时依然存在。 咱们推断,在业务高峰期,该节点呈现了大对象降职到了老年代,导致内存应用迅速回升,并且大对象没有被及时回收。那如何找到这个大对象及其产生的起因呢?为了升高问题排查期间业务的损失,提出了长期的故障转移策略,尽量升高异样数量。 步骤2  故障转移策略在api服务调用core服务出现异常时,将出现异常的机器ip上报给监控平台。而后利用监控平台的统计与告警能力,配置相应的告警规定与回调函数。当异样触发告警,通过配置的回调函数将告警ip传递给api服务,此时api服务能够将core服务下的该ip对应的机器视为“故障”,进而通过自定义的故障转移策略(实现Dubbo的AbstractLoadBalance抽象类,并且配置在我的项目),主动将该ip从提供者集群中剔除,从而达到不去调用问题机器。图 4 是整个措施的流程。在该措施上线前,每当有机器内存告警时,将会人工重启该机器。 图4 故障转移策略 步骤3  大对象优化大对象占用了较多的内存,导致内存空间无奈被无效利用,甚至造成OOM(Out Of Memory)异样。在优化过程中,先是查看了异样期间的线程信息,而后对堆内存进行了剖析,最终确定了大对象身份以及产生的接口。 (1) Dump Stack 查看线程 从监控平台上Dump Stack文件,发现肯定数量的如下线程调用。 Thread 5612: (state = IN_JAVA) - org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encodeResponse(org.apache.dubbo.remoting.Channel, org.apache.dubbo.remoting.buffer.ChannelBuffer, org.apache.dubbo.remoting.exchange.Response) @bci=11, line=282 (Compiled frame; information may be imprecise) - org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encode(org.apache.dubbo.remoting.Channel, org.apache.dubbo.remoting.buffer.ChannelBuffer, java.lang.Object) @bci=34, line=73 (Compiled frame) - org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.encode(org.apache.dubbo.remoting.Channel, org.apache.dubbo.remoting.buffer.ChannelBuffer, java.lang.Object) @bci=7, line=40 (Compiled frame) - org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalEncoder.encode(io.netty.channel.ChannelHandlerContext, java.lang.Object, io.netty.buffer.ByteBuf) @bci=51, line=69 (Compiled frame) - io.netty.handler.codec.MessageToByteEncoder.write(io.netty.channel.ChannelHandlerContext, java.lang.Object, io.netty.channel.ChannelPromise) @bci=33, line=107 (Compiled frame) - io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(java.lang.Object, io.netty.channel.ChannelPromise) @bci=10, line=717 (Compiled frame) - io.netty.channel.AbstractChannelHandlerContext.invokeWrite(java.lang.Object, io.netty.channel.ChannelPromise) @bci=10, line=709 (Compiled frame)...state = IN_JAVA 示意Java虚拟机正在执行Java程序。从线程调用信息能够看到,Dubbo正在调用Netty,将输入写入到缓冲区。此时的响应可能是一个大对象,因此在对响应进行编码、写缓冲区时,须要消耗较长的工夫,导致抓取到的此类线程较多。另外耗时长,也即是大对象存活工夫长,导致full gc 开释的内存越来越小,闲暇的堆内存变小,这又会加剧full gc 次数。 ...

August 28, 2023 · 2 min · jiezi

关于内存:深入了解-JavaScript-内存泄漏

作者:京东批发 谢天在任何语言开发的过程中,对于内存的治理都十分重要,JavaScript 也不例外。 然而在前端浏览器中,用户个别不会在一个页面停留很久,即便有一点内存透露,从新加载页面内存也会跟着开释。而且浏览器也有本人的主动回收内存的机制,所以前端并没有特地关注内存透露的问题。 然而如果咱们对内存透露没有什么概念,有时候还是有可能因为内存透露,导致页面卡顿。理解内存透露,如何防止内存透露,都是不可短少的。 什么是内存在硬件级别上,计算机内存由大量触发器组成。每个触发器蕴含几个晶体管,可能存储一个位。单个触发器能够通过惟一标识符寻址,因而咱们能够读取和笼罩它们。因而,从概念上讲,咱们能够把咱们的整个计算机内存看作是一个微小的位数组,咱们能够读和写。这是内存的底层概念,JavaScript 作为一个高级语言,不须要通过二进制进行内存的读写,而是相干的 JavaScript 引擎做了这部分的工作。 内存的生命周期内存也会有生命周期,不论什么程序语言,个别能够依照程序分为三个周期: 调配期:调配所须要的内存使用期:应用调配的内存进行读写开释期:不须要时将其开释和偿还内存调配 -> 内存应用 -\> 内存开释 什么是内存透露在计算机科学中,内存透露指因为忽略或谬误造成程序未能开释曾经不再应用的内存。内存透露并非指内存在物理上的隐没,而是应用程序调配某段内存后,因为设计谬误,导致在开释该段内存之前就失去了对该段内存的管制,从而造成了内存的节约。如果内存不须要时,没有通过生命周期的的开释期,那么就存在内存透露。 内存透露的简略了解:无用的内存还在占用,得不到开释和偿还。比较严重时,无用的内存会继续递增,从而导致整个零碎的卡顿,甚至解体。 JavaScript 内存管理机制像 C 语言这样的底层语言个别都有底层的内存治理接口,然而 JavaScript 是在创立变量时主动进行了内存调配,并且在不应用时主动开释,开释的过程称为“垃圾回收”。然而就是因为主动回收的机制,让咱们谬误的感觉开发者不用关怀内存的治理。 JavaScript 内存管理机制和内存的生命周期是统一的,首先须要分配内存,而后应用内存,最初开释内存。绝大多数状况下不须要手动开释内存,只须要关注对内存的应用(变量、函数、对象等)。 内存调配JavaScript 定义变量就会主动分配内存,咱们只须要理解 JavaScript 的内存是主动调配的就能够了。 let num = 1;const str = "名字";const obj = { a: 1, b: 2}const arr = [1, 2, 3];function func (arg) { ... }内存应用应用值的过程实际上是对调配的内存进行读写的操作,读取和写入的操作可能是写入一个变量或者一个对象的属性值,甚至传递函数的参数。 // 持续上局部// 写入内存num = 2;// 读取内存,写入内存func(num);内存回收垃圾回收被称为GC(Garbage Collection) 内存透露个别都是产生在这一步,JavaScript 的内存回收机制尽管能够回收绝大部分的垃圾内存,然而还是存在回收不了的状况,如果存在这些状况,须要咱们本人手动清理内存。 以前一些老版本的浏览器的 JavaScript 回收机制没有那么欠缺,经常出现一些 bug 的内存透露,不过当初的浏览器个别都没有这个问题了。 这里理解下当初 JavaScript 的垃圾内存的两种回收形式,相熟一下这两种算法能够帮忙咱们了解一些内存透露的场景。 ...

March 21, 2023 · 3 min · jiezi

关于内存:浅析大促备战过程中出现的fullGc我们能做什么

作者:京东科技 白洋 前言:背景:为应答618、双11大促,生产金融侧会依据批发侧大促节奏进行整体零碎备战。对外围流量入口承载的零碎进行加固优化,排除零碎危险,保障大促期间零碎稳固。因为大促期间,生产金融业务承当着直面用户,高并发,零碎危险大概率间接造成资损危险等问题。 在日常压测和大促期间,常常会产生Jvm呈现大量young Gc 和 局部full GC的状况,导致性能降落,可用率升高等状况。之前对Jvm的垃圾回收机制不是很熟,如何防止和如何调优,基本上无所不通,本文也是对本人学到的常识的一个坚固~一、什么是JVM的GC?JVM(Java Virtual Machine)。JVM 是 Java 程序的虚拟机,是一种实现 Java 语言的解释器。 它提供了一种独立于操作系统的运行环境,使得 Java 程序在任何反对 JVM 的计算机上都能够运行。JVM 负责加载、验证、解释、执行和垃圾回收 Java 字节代码,并为 Java 程序提供内存治理、线程治理和安全控制等服务。 JVM 中的 GC(Garbage Collection)是垃圾回收的缩写,是 JVM 的内存管理机制。 Young GC 和 Full GC 是两种不同的 GC 算法。 Young GC:针对新生代对象的回收算法,通常应用的是复制算法或者标记整顿算法。因为新生代中的对象生命周期短,所以 Young GC 速度要比 Full GC 快得多。 Full GC:针对整个堆内存的回收算法,用于回收那些在 Young GC 中没有回收的存活对象。Full GC 速度比较慢,因为它须要扫描整个堆内存,因而对系统的性能影响较大。 所以在设计 Java 利用时,须要尽量减少 Full GC 的次数,以保证系统的性能。常见的办法包含扩充新生代的内存空间,缩小数组长度等。 以上根本是通用的对 Jvm 和 Gc 的解释。然而能够显著看出短少一些细节,对咱们来说还是没什么用,测试同学该如何了解具体的场景呢?? 咱们首先来了解young GC 的诞生过程: 首先, 了解复制算法和标记整顿算法,它们是两种不同的 Young GC 回收算法。 ...

March 1, 2023 · 3 min · jiezi

关于内存:堆内存持续占用高-且-ygc回收效果不佳-排查处理实践

作者:京东批发 王江波 阐明:局部素材来源于网络,数据分析全为实在数据。一、 问题背景自建的两套工具,运行一段时间后均呈现 内存占用高触发报警,频繁young gc且成果不佳。已经尝试屡次解决,因各种起因耽误,最近下定决心解决此问题。 二、 问题形容Q:堆内存1018M,应用达到950M左右触发一次young gc,ygc之后内存占用630M,未产生full gc 三、 容器配置已解决要害信息 •主机名 xxx •实例ID xxx •ip •操作系统名称Linux •操作系统体系结构amd64 •CPU个数2 •JRE版本1.8.0_191 •JVM启动工夫2023-02-18 17:14:10.873 •启动门路/export/App •Full GCPS MarkSweep •Young GCPS Scavenge •过程ID115135 •物理内存大小251.4GB(269888389120Byte) •替换区大小0.0GB(0Byte) •虚拟内存大小12.5GB(13368197120Byte) •利用门路/export/App/lib/tp-center-web.jar!/BOOT-INF/lib/ •JVM启动参数-javaagent:/export/xxx/lib/pfinder-profiler-agent-1.0.8-20210322032622-6f12bda2.jar -Ddeploy.app.name=xxx -Ddeploy.app.id=xxx -Ddeploy.instance.id=0 -Ddeploy.instance.name=server1 -DJDOS_DATACENTER=HT -Dloader.path=./conf -Dspring.profiles.active=pre -Xms1024m -Xmx1024m -Xmn384m -XX:MetaspaceSize=64m -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:ParallelGCThreads=2 -XX:CICompilerCount=2 -XX:MaxDirectMemorySize=128m -Duser.timezone=Asia/Shanghai -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=xxx -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=xxx 四、 问题剖析1、 young gc的机会?R:ygc在新生代的eden区满了之后就会触发,采纳复制算法回收新生代的垃圾。 2、 为何young gc后堆内存使用率依然很高?R:新生代过小,大对象间接进入老年代,编码时要尽量减少大对象的应用。 3、 full gc 的机会?R:HotSpot VM里,除了CMS之外,其它能收集老年代的GC都会同时收集整个GC堆,包含新生代 ...

March 1, 2023 · 4 min · jiezi

关于内存:慧销平台ThreadPoolExecutor内存泄漏分析

作者:京东批发 冯晓涛 问题背景京东生旅平台慧销零碎,作为平台零碎对接了多条业务线,次要进行各个业务线广告,召回等流动相干内容与能力治理。 最近依据告警发现内存继续升高,每隔2-3天会收到内存超过阈值告警,猜想可能存在内存透露的状况,而后进行排查。依据24小时时间段内存监控能够发现,容器的内存在持续上升: 问题排查初步预计内存透露,查看24小时时间段jvm内存监控,排查jvm内存回收状况: YoungGC和FullGC状况: 通过jvm内存剖析和YoungGC与FullGC执行状况,能够判断可能起因如下: 1、 存在YoungGC然而没有呈现FullGC,可能是对象进入老年代然而没有达到FullGC阈值,所以没有触发FullGC,对象始终存在老年代无奈回收 2、 存在内存透露,尽管执行了YoungGC,然而这部分内存无奈被回收 通过线程数监控,察看以后线程状况,发现以后线程数7427个,并且还在一直回升,根本判断存在内存透露,并且和线程池的不当应用无关: 通过JStack,获取线程堆栈文件并进行剖析,排查为什么会有这么多线程: 发现通过线程池创立的线程数达7000+: 代码剖析剖析代码中ThreadPoolExecutor的应用场景,发现在一个worker公共类中定义了一个线程池,worker执行时会应用线程池进行异步执行。 public class BackgroundWorker { private static ThreadPoolExecutor threadPoolExecutor; static { init(15); } public static void init() { init(15); } public static void init(int poolSize) { threadPoolExecutor = new ThreadPoolExecutor(3, poolSize, 1000, TimeUnit.MINUTES, new LinkedBlockingDeque<>(1000), new ThreadPoolExecutor.CallerRunsPolicy()); } public static void shutdown() { if (threadPoolExecutor != null && !threadPoolExecutor.isShutdown()) { threadPoolExecutor.shutdownNow(); } } public static void submit(final Runnable task) { if (task == null) { return; } threadPoolExecutor.execute(() -> { try { task.run(); } catch (Exception e) { e.printStackTrace(); } }); } }广告缓存刷新worker应用线程池的代码: ...

February 28, 2023 · 3 min · jiezi

关于内存:10分钟读懂虚拟内存-IO-零拷贝

虚拟内存 (一)虚拟内存引入 咱们晓得计算机由CPU、存储器、输出/输出设备三大外围局部组成,如下 CPU运行速度很快,在齐全现实的状态下,存储器应该要同时具备以下三种个性: 速度足够快:这样 CPU 的效率才不会受限于存储器;容量足够大:容量可能存储计算机所需的全副数据;价格足够便宜:价格低廉,所有类型的计算机都能装备;然而,出于老本思考,以后计算机体系中,存储都是采纳分层设计的,常见档次如下: 上图别离为寄存器、高速缓存、主存和磁盘,它们的速度逐级递加、老本逐级递加,在计算机中的容量逐级递增。通常咱们所说的物理内存即上文中的主存,常作为操作系统或其余正在运行中的程序的长期材料存储介质。在嵌入式以及一些老的操作系统中,零碎间接通过物理寻址形式和主存打交道。然而,随着科技倒退,遇到如下困境: 一台机器可能同时运行多台大型应用程序;每个应用程序都须要在主存存储大量长期数据;晚期,单个CPU寻址能力2^32,导致内存最大4G。主存成了计算机系统的瓶颈。此时,科学家提出了一个概念:虚拟内存。 以32位操作系统为例,虚拟内存的引入,使得操作系统能够为每个过程调配大小为 4GB的虚拟内存空间,而实际上物理内存在须要时才会被加载,无效解决了物理内存无限空间带来的瓶颈。在虚拟内存到物理内存转换的过程中,有很重要的一步就是进行地址翻译,上面介绍。 (二)地址翻译 过程在运行期间产生的内存地址都是虚拟地址,如果计算机没有引入虚拟内存这种存储器形象技术的话,则 CPU 会把这些地址间接发送到内存地址总线上,而后拜访和虚拟地址雷同值的物理地址;如果应用虚拟内存技术的话,CPU 则是把这些虚拟地址通过地址总线送到内存治理单元(Memory Management Unit,简称 MMU),MMU 将虚拟地址翻译成物理地址之后再通过内存总线去拜访物理内存: 虚拟地址(比方 16 位地址 8196=0010 000000000100)分为两局部:虚构页号(Virtual Page Number,简称 VPN,这里是高 4 位局部)和偏移量(Virtual Page Offset,简称 VPO,这里是低 12 位局部),虚拟地址转换成物理地址是通过页表(page table)来实现的。页表由多个页表项(Page Table Entry, 简称 PTE)组成,个别页表项中都会存储物理页框号、批改位、拜访位、爱护位和 "在/不在" 位(无效位)等信息。这里咱们基于一个例子来剖析当页面命中时,计算机各个硬件是如何交互的: 第 1 步:处理器生成一个虚拟地址 VA,通过总线发送到 MMU;第 2 步:MMU 通过虚构页号失去页表项的地址 PTEA,通过内存总线从 CPU 高速缓存/主存读取这个页表项 PTE;第 3 步:CPU 高速缓存或者主存通过内存总线向 MMU 返回页表项 PTE;第 4 步:MMU 先把页表项中的物理页框号 PPN 复制到寄存器的高三位中,接着把 12 位的偏移量 VPO 复制到寄存器的末 12 位形成 15 位的物理地址,即能够把该寄存器存储的物理内存地址 PA 发送到内存总线,拜访高速缓存/主存;第 5 步:CPU 高速缓存/主存返回该物理地址对应的数据给处理器。在 MMU 进行地址转换时,如果页表项的无效位是 0,则示意该页面并没有映射到实在的物理页框号 PPN,则会引发一个缺页中断,CPU 陷入操作系统内核,接着操作系统就会通过页面置换算法抉择一个页面将其换出 (swap),以便为行将调入的新页面腾出地位,如果要换出的页面的页表项里的批改位曾经被设置过,也就是被更新过,则这是一个脏页 (Dirty Page),须要写回磁盘更新该页面在磁盘上的正本,如果该页面是"洁净"的,也就是没有被批改过,则间接用调入的新页面笼罩掉被换出的旧页面即可。缺页中断的具体流程如下: ...

November 17, 2022 · 3 min · jiezi

关于内存:Datenlord-内存顺序问题二

上一篇文章介绍了内存模型,并介绍了两种内存程序, memory_order_acquire(Acquire)和memory_order_release(Release)。 集体认为,这两种内存程序是C++定义的六种内存程序中最重要的两种, 只有了解了Acquire和Release的语义,能力更好了解其余四种内存程序的语义。 更进一步,在理论应用场景中,Acquire和Release是最常见的两种内存程序。 如何判断该应用哪种内存程序?这是开发者在应用原子类型和无锁化编程时最常碰到的问题。 本篇Blog用理论的例子来阐明,如何判断该应用哪种内存程序。 此外,为了更深刻了解基于原子操作和基于锁实现的同步关系的本质区别, 本篇Blog还会介绍Happen-Before关系和Synchronize-With关系。 Happen-Before关系线程间的同步关系,是要约定不同线程里产生的事件的先后秩序,互斥关系实质也是一种同步关系。 Happen-Before关系就是用于定义不同事件之间的先后秩序。 Happen-Before关系能够是在代码里动态约定好(基于锁的形式),也能够是在程序运行时动静发现(基于原子操作和内存程序的形式)。 先来看一个简略的例子,这个例子解释了Happen-Before关系: int data = 0;int flag = 0;// thread 1void thread_func1() { data = 42; flag = 1; // 事件1}// thread 2void thread_func2() { if (flag == 1) // 事件2 printf("%d", data);}下面的例子里定义了两个全局变量,线程1设置flag = 1示意实现对data的赋值, 线程2读取flag的值用以判断线程1是否实现对data的赋值,如果flag == 1则输入data的值。 咱们定义两个事件,事件1为thread_func1里对flag赋值示意对data的赋值实现, 事件2为thread_func2里判断flag == 1,如果flag == 1则输入data的值。 因为没有用锁的形式在代码里动态规约事件1和事件2的先后顺序,程序运行时能够有多种后果, 有些后果是正当的,有些后果是不合理的。 其中两种正当的后果是:要么线程2输入data的值42,要么不输入。 也就是说要么事件1 Happen-Before事件2,要么事件2 Happen-Before事件1。 然而,还有些不合理的后果,比方线程2有可能输入data的值为0,为什么呢? 因为编译器或CPU会对程序进行优化,使得指令的执行程序跟代码的逻辑程序不统一。比方编译器可能对thread_func2进行如下优化: // thread 2void thread_func2() { int tmp = data; if (flag == 1) printf("%d", tmp);}这里tmp代表某个寄存器,编译器优化thread_func2导致在判断flag == 1前把data的值先载入寄存器,此时data的值可能为0, 判断完flag == 1之后再输入寄存器的值,此时即使data曾经被thread_func1赋值为1,然而寄存器tmp里的值依然是0。 也就是说,程序运行时产生不合理的后果,是因为没有保障事件1和事件2之间的先后秩序,导致两个事件在运行时有重叠。 因而,为了保障下面的例子运行产生正当的后果,咱们须要确保要么事件1 Happen-Before事件2,要么事件2 Happen-Before事件1。 能够采纳基于锁的信号量机制,在代码里动态约定事件1在事件2之前产生, 也能够采纳原子操作和内存程序在程序运行时动静发现事件1和事件2之间的关系。 ...

July 19, 2022 · 2 min · jiezi

关于内存:Datenlord-内存顺序问题一

内存程序,艰深地讲,是对于代码编译成机器指令后的执行程序问题。内存程序和编译器、硬件架构密切相关。那为什么会产生内存程序问题呢?有两方面起因: 一方面,编译器为了优化程序性能,不会齐全依照开发者写的代码的程序来生成机器指令; 另一方面,在程序运行时,为了进步性能,CPU也不齐全依照程序的指令程序执行,比方体系结构里经典的Tomasulo算法。 对于大部分开发者而言,在写单线程程序,或者基于锁(Mutex)和信号量(Semaphore)之类编程框架提供的同步元语写多线程程序的时候,并不需要关怀内存程序的问题。 这是因为编译器和硬件架构保障了,尽管指令执行程序可能跟开发者写的代码语句的程序不统一,然而执行后的后果是一样的,即语义统一。 换句话讲,编译器和硬件架构提供了一层形象用以屏蔽内存程序问题,保障代码和编译进去的程序执行语义统一。 这样一方面进步程序性能,另一方面让开发者不必关怀底层细节。编译器和硬件架构提供的这一层形象叫作内存模型(Memory Model)。 这种为了便于了解和应用而提出一层形象以屏蔽底层简单细节的做法,在各个学科中亘古未有。 类比经典力学和相对论,在远低于光速的静止中,实用经典力学,在靠近或达到光速的静止中,实用相对论而不实用经典力学; 经典力学和相对论之间,有一层形象,速度远低于光速,形象成立,速度靠近或达到光速,形象被突破。 相似的,编译器和硬件架构提供了内存模型这一层形象用以屏蔽内存程序问题。 对于大部分开发者而言,写单线程程序,或基于编程框架提供的同步元语写多线程程序的时候,内存模型形象成立,无需思考内存程序问题; 当开发者写多线程程序,对于多线程并发拜访(或读或写)共享数据,应用原子操作,而不是基于锁互斥拜访数据,即无锁化编程的时候, 这时内存模型的形象被突破,开发者必须思考内存程序问题。 内存程序问题波及编译器和硬件架构的很多细节,我尝试用对于大部分开发者来说浅显易懂的语言来形容内存程序问题, 尽可能防止编译器和硬件架构的实现细节,以便于大家了解。 上面顺次介绍内存模型、内存程序、原子操作,最初以C++11为例解说开发者如何规约内存程序。 内存模型内存模型是编程语言对程序运行时内存拜访模式的形象,即内存被多个程序(过程和线程)共享,程序对内存的拜访是无奈预知的。 艰深地讲,内存模型指的是CPU并发随机拜访内存,或从内存加载数据(Load)或把数据写入到内存(Store)。 Load和Store是机器指令(或汇编语言)的术语,其实就是读(Read)操作和写(Write)操作。 这里,内存模型屏蔽了很多硬件的细节,比方CPU的寄存器、缓存等等(因为寄存器和缓存属于程序执行上下文,CPU拜访寄存器和缓存不存在并发)。 内存模型比拟好了解,每个开发者或多或少都接触到内存模型。 有了内存模型这一层形象,那么内存程序问题能够等价于读操作和写操作的执行程序问题,因为内存模型里CPU对内存的拜访只有读和写两种操作。 开发者在写代码时,代码语句的先后顺序往往约定了对内存拜访的先后顺序的,即便拜访的不是同一个内存地址。然而这个约定是基于内存模型这层形象成立的前提。 后面提到,内存模型在单线程编程和基于编程框架提供的同步元语实现多线程编程的状况下,对内存程序问题进行屏蔽,怎么了解呢? 上面通过例子阐明单线程程序的内存程序问题: int x, y = 0;x = y + 1;y = 2;这段代码定义了两个整数,x和y,并对y初始化赋值为0,而后给x赋值的时候用到y的值,之后再给y赋值。 看上去,对y的写操作必须在对x的写操作之后,然而改写上述代码片段如下: int x, y = 0;int tmp;tmp = y;y = 2;x = tmp + 1;减少了变量tmp之后,首先把y的值付给tmp,而后就能够先对y赋新值,再给x赋值。对x和y来说,下面两段程序的执行后果是等价的。 变量tmp在这里能够了解为是CPU的寄存器,有了寄存器的帮忙,代码里的读操作和写操作先后顺序可能被扭转。 艰深地讲,编译器对代码语句的程序调整也是相似的原理 (仅供对编译器不熟的读者了解编译器如何对代码语句程序的调整,理论编译器对代码的优化很简单,细节暂不开展)。 上述例子阐明了,单线程状况下,内存模型的形象成立,开发者无需思考内存程序问题。 再思考多线程的状况,把对x的写操作和对y的写操作放在不同的线程里: int x, y = 0;void thread_func1() { x = y + 1;}void thread_func2() { y = 2;}能够看出,x会有多种后果,取决于程序运行时两个线程的执行程序,这就跟之前单线程的执行后果不统一了。 因为这里没有采纳编程框架提供的同步元语来实现线程间同步,内存模型的形象被突破,编译器和硬件架构无奈保障语义统一。 此时,开发者要么采纳编程框架提供的同步元语实现线程间同步以满足内存模型的形象,要么显式规约指令执行程序以保障后果正确。 改写下面的例子,能够采纳编程框架提供的同步元语,规约程序运行时线程的执行程序,这里应用信号量来实现线程间同步: ...

July 18, 2022 · 2 min · jiezi

关于内存:Mac系统占用空间大空间不够查看系统文件大小分布

背景: 最近老提醒空间不够,很难堪,始终弹零碎提醒 如图,256的空间,就剩下几个G了,其中最大头的零碎占用:160G,占比60%多 失常状况下:咱们能够点击治理,进入到零碎磁盘优化界面: 这种实用于简略的文件占用剖析,个别咱们可能通过 清理文稿 和 回收箱 来解决空间不够的问题。 1、清空回收站。 2、在文稿里,按文件大小排序,删除不须要的文件。 3、对于GarageBand,这个是零碎上的模仿乐器,个别都应用不到。 革除办法: rm -rf /Library/Application\ Support/GarageBandrm -rf /Library/Application\ Support/Logicrm -rf /Library/Audio/Apple\ Loops 不过,对于罪魁祸首,零碎的160G,咱们怎么能力晓得她的外部存储散布呢? 注释: 对于如何查看零碎的文件占用详情。 一、首先关上终端,输出 du -sh *这个命令用来查看根目录下,所有文件的大小散布,如图所示: 其中,咱们很容易能看到每个文件的大小占比,疾速定位到最大占比的文件:Library 二、输出命令,进入到Library文件门路 cd ~/Library 而后,查看Library下的所有文件大小散布。 输出: du -d 1 -h 很容易咱们能够找到最大的文件:/Developer 当然,其余的文件大小,咱们也都能看到,高深莫测。 三、到这里,咱们根本就能晓得上面的套路了,咱们能够持续往下查看 比方,我这里持续进入到Developer文件,再查看他的每个子文件大小: 根本,查看个两三层,就根本能晓得大略的起因了,我这边因为是程序猿,所以Xcode是根本原因,占了零碎160G的一半大小。 到这里为止,如果你也是程序猿,有趣味的,能够持续看;如果没有趣味的能够间接跳第四步。 根本这就到底了,大略的空间占用散布从下面几张图,也根本无数了。 以上是讲如何查看及剖析文件,如果你是iOS程序猿,这边附上几个清理步骤(清理Xcode缓存) 通过测试,我临时发现这几个文件能够适当清理下: 1 ./Archives 这个文件存储的是你所有的历史打包文件,你能够将一些历史的包删掉,最近的如果不释怀能够先留着,不过全副删除也是没问题的,然而,如果你删除了,咱们Xcode打包上传界面就看不到货色了(如下图所示,该界面的货色就没了) 2 ./DerivedData 这个文件大家应该比拟相熟了,存储的是所有我的项目的一些缓存数据、包含编译缓存文件等等,这个文件是能够全副清理的,当然,你也能够保留一些最近的我的项目,先临时清理历史我的项目的缓存。 3 ./iOS DeviceSupport 这个文件外面存储的是xcode对手机各个版本的反对文件,这里如果你的我的项目不再须要反对iOS6、iOS7等,能够先把外面的基于iOS6、iOS7的反对文件革除。 4 附上 完整版Xcode瘦身办法大全 ,有趣味的可对照此文操作。 四、通过第三步的层层剖析,咱们根本能晓得了每个文件的大小散布,也能找到一些不须要用的垃圾文件,其中大多以缓存文件居多,大家能够适当进行清理~ 最初,如果有对命令不感冒的人,也能够通过Finder来进行可视化的查看。 关上Spotlight(Ctrl+空格),输出 ~/Library 能进入到资源库文件门路: 最左边的文件就对应方才命令进去的文件,咱们能够依据命令查找到的占用最大的文件,这里点进去查看,而后再依据本人的需要进行适当清理。 ...

July 2, 2022 · 1 min · jiezi

关于内存:内存不超过5Mdatop-在识别冷热内存及跨-numa-访存有多硬核-龙蜥技术

datop 是一款轻量级实时性内存冷热扫描工具,可能扫描内存冷热以及跨 muma 访存的状况,其运行时开销和存储空间十分小(单 CPU 使用率不到 4% 和 5MB),此外不受硬件平台的限度,在物理机和虚拟机上均能反对。目前曾经在龙蜥社区开源了,内核态的局部代码是基于 OpenAnolis 5.10。 开源地址: https://gitee.com/anolis/data-profile-tools.git 以下是 Cloud Kernel SIG 核心成员分享《datop 轻量级靶向内存热点扫描工具介绍与入门》局部内容(视频回顾和技术PPT获取形式见文末)。 DRAM 内存低容量对系统造成性能影响日益突出,云计算场景中为缓解日益增长的内存需要,业界提出异构内存的应用,采纳两种或更多类型的内存:小型高性能内存以及大容量的低性能内存。此外,古代高端存储设备如固态驱动器和相位扭转内存,为进步内存性能提供了可能, 这些代替计划给人一种谬误的幻觉,认为轻易能通过筛选数据的热度来抉择寄存的设施,的确这些信息在现有的内存治理中,能够通过全盘扫描内存冷热的形式失去, 然而长时间扫描过程中很容易产生极大的开销,造成零碎性能损耗。 以后现有内存冷热扫描机制缺点: 热点跟踪开销成比例增长:监控的内存越多,开销越大跟踪品质升高:监控内存范畴越大,监控品质降落越显著短少 numa 访存统计:跨 numa 访存性能影响不可疏忽针对上述问题,咱们开发了跟踪实时内存热点数据的工具 datop(Data Access Top), 采纳划分内存区域采样的形式,并自适应区域构建技术来获取极低的开销损耗,在此基础上,还减少了 numa 仿真性能,用于收集工作跨 numa 访存状况,为了评估其准确性和低开销能力,咱们选取和测试了多个 benchmark,并与基线进行比拟,结果表明:datop 工具在辨认冷热内存以及跨 numa 访存方面具备优良的体现能力。 具体分享提纲有以下 6 局部: 1、datop 的概述 2、背景:云计算大规模简单场景下内存面临的挑战 3、datop 开发设计和指标 4、热点扫描原理及策略 5、datop 工具测试状况阐明 6、datop 演示与试用及后续布局和思考 规范 datop 演示与应用,利用 datop 工具去监控测试用例 numactl -m 0 -C 30 memhog -r1000000000 100m 热点内存散布以及跨 numa 状况。 ...

May 5, 2022 · 1 min · jiezi

关于内存:硬盘可以分为几类监控专用硬盘和普通硬盘有什么区别

硬盘分为绿盘黑盘蓝屏紫盘红盘。不同色彩的硬盘性能侧重点不一样,能够利用在不同的畛域。这种色彩分级办法是西部数据公司特有的硬盘分级办法。 如何正确抉择一款性价比高的硬盘就会省去很大的前期保护老本,那么专用监控硬盘和一般硬盘区别体现在哪些方面呢? 硬盘按色彩分大抵有:彩色、蓝色、绿色、红色、紫色 、金盘6种 黑盘:彩色硬盘具备杰出的性能和高转速,多实用于电脑服务器以及企业级硬盘,当然价格也是最高的,适宜对性能及稳定性要求极高的用户,然而,黑盘因为转速较高,在应用时应防止激烈触动避免磁头撞击碟片而损坏 蓝盘:是介于绿盘和黑盘之间,通常用的就是蓝盘,性能及容量在几种硬盘中属于中规中矩的,但其性价比十分高,因而广泛应用于生产级PC市场,其毛病就是声音较大(注:当初的绿盘和蓝盘基本上就没区别了) 绿盘:盘属于大容量存储磁盘,功耗较低,侧重于节能,性能绝对个别,但实用于长期保留文件。(注:当初的绿盘和蓝盘基本上就没区别了) 红盘:红盘具备更大的容量、低转速和乐音较小的特点,适宜有搭建网络存储的集体及小型办公用户。 紫盘:紫盘是为监控硬盘录像设施专门设计的,适宜365天×24小时不间断地运行,能够极低的功耗全天候24小时继续读写。 金盘:失常名称是Gold,即金盘,价格昂贵享有五年保固,WDGold 硬盘的工作负载容量远高于个别硬盘,采纳多项技术,可提供更高的可靠性、容量、效用和性能。专为大量数据中心的应用程序而设计,非常适合用于须要高度牢靠存储设备并提供全天候反对的高可用性服务器和存储阵列,包含中小型企业服务器与存储、机架数据中心服务器、存储集群等。 从这个数据来看,一般硬盘并不适宜长时间间断读写,如果长时间不间断读写的话,势必会不堪重负呈现问题;而监控级硬盘能够实现7*24全年无休的继续工作。紫盘反对相当于一般硬盘3倍的工作负载评级,能够更好地满足视频监控零碎的超高需要。因而在稳定性和可靠性方面,监控硬盘无疑胜出一筹。1.硬盘的寿命 监控硬盘是一种比一般硬盘更实用的硬盘。 一般硬盘在上电启动的时候会全速启动,霎时电流可能达到2安,甚至更高。 而监控硬盘启动的时候会迟缓减速,启动电流会管制在2安以下。因为监控零碎中通常会装置多个硬盘,这样在启动的霎时会产生很大的启动电流,如果是一般硬盘的话,电源会难以承受,甚至烧毁。 另外,监控系统对硬盘的传输速度要求个别不高,然而会频繁的小数据量的读写。 所以须要在磁头读写机构上针对监控零碎的读写特点做构造优化设计,以缩短磁头的寿命。 监控硬盘的实践均匀无故障运行工夫比一般电脑硬盘要长得多,稳定性、可靠性要更高。 2.间断工作工夫差异 一般电脑硬盘的设计以8×5为根底。8×5指的是一般一般电脑硬盘每天工作8个小时,每周工作5天(硬盘工作是指硬盘处于读写状态。须要特地留神的是硬盘加电后有两个状态:工作状态和期待状态,其中工作状态是硬盘进行读写工作,期待状态是硬盘没有进行读写工作但处于待命状态。)监控硬盘是按24×7的企业级环境要求进行设计开发的。24×7就是每天工作24个小时,每周工作7天(就是连续不断的进行工作)。所以一般电脑硬盘并不适宜长时间间断读写,如果要求一般电脑硬盘长时间间断读写就会极大的伤害硬盘,使硬盘出现异常声音、读写谬误、工作停止等多种问题并由此导致硬盘最终损坏。硬盘录像机是长年不间断运行的,因而要求硬盘必须能够长时间间断工作,能满足这个要求的就是监控硬盘。 3.启动差异 市面上大多数硬盘都蕴含电机零碎,因而硬盘加电启动的时候与电机加电启动的状况相相似:就是在加电的初始工夫会呈现较大的启动电流以实现硬盘启动。如果加电启动的时候硬盘内部供电系统不能保障足够的电流反对,则硬盘会启动失败,导致硬盘不可用。并且如果屡次呈现这种状况,容易造成硬盘的损坏。因为硬盘电机的供电是由内部电源零碎直流12V满足的,因而在评估硬盘启动电流的时候都以直流12V的电流为规范。 一般电脑硬盘启动电流个别在2.8A~3.2A之间。监控硬盘的启动电流最高为2.0A。数字硬盘录像机常常采纳多硬盘进行数据存储,以装置8片硬盘为例:一般电脑硬盘启动电流2.8×8=22.4A,最低的功耗为22.4A×12V=268.8W。DVR专用硬盘启动电流2.0A×8=16A,最高的功耗为16A×12V=192W。 能够看出,在雷同硬盘数量的状况下监控硬盘对外部电源零碎的要求更低(在同样输出功率的内部电源反对下,能够装置的DVR专用硬盘的数量会更多)。 阐明:在上例的状况中,如果内部电源零碎供电只能保障250W,则采纳一般PC硬盘的时候会呈现某些硬盘能够辨认,某些硬盘不能够辨认,并且没有规律性。 4.运行功耗及散热差异 这里的运行功耗是指硬盘在失常读写状态时的功耗。PC硬盘的运行功耗个别为14.5瓦左右,监控硬盘的运行功耗个别为8瓦左右。能够看出,监控硬盘运行功耗仅相当于一般电脑硬盘功耗的55%,低的运行功耗不仅对电源零碎有重要意义,而且对数字硬盘录像机零碎的散热也有重要的意义(运行功耗中大略75%会转变为热能)。 在数字硬盘录像机中,如果装置8片硬盘,那一般PC硬盘的运行总功耗为14.5W×8=116W,DVR专用硬盘的运行总功耗为8W×8=64W。如果采纳一般PC硬盘,能够想像在数字硬盘录像机这么小的空间内有这么高的发热源,对系统的散热要求是很高的,为了保障硬盘有一个正当的环境温度(0~60℃),必须对硬盘零碎进行无效的散热。而采纳DVR专用硬盘,发热状况就好得多—-升高了零碎散热要求使系统对环境的适应性更强。 5.传输差异 监控硬盘除了采纳传统电脑硬盘的传输模式,还引入了一个更新的传输模式—-不间断传输模式,该传输模式最大为65MB/S。通过引入不间断传输模式,使硬盘对流媒体的反对更加牢靠,充沛保障数字硬盘录像机在录入的同时进行回放的流畅性和稳定性。这是其它硬盘所不具备的个性。 6.价格差异 相比一般电脑硬盘,监控硬盘在价格上与其相差无几,只是在非凡技术上的反对有所不同,前者更重视性能后者则重视稳固读写。只有企业级硬盘才绝对贵一些,毕竟要求更加刻薄一些。 7.硬盘寻道工夫 监控的最大特点是要求硬盘长时间继续写入,反而对数据读取没有太高要求。这一点一般硬盘从设计上就基本不能符合要求。一般硬盘在家用环境下往往是随机小文件读写谋求寻道速度快,而监控硬盘则适宜间断大文件继续写入,具备良好的稳定性。 对于工程商而言,装置监控硬盘稳固了,前期保护服务老本升高,同时客户对你的口碑也会晋升,让客户释怀,利润天然减少。对于客户而言,故障少了,数据失落危险就小,数据安全性进步,让监控起到应有的防护作用,两全其美! 官网:http://www.xmjisujia.cn 公众号:极速佳

November 1, 2021 · 1 min · jiezi

关于内存:物理内存管理连续内存分配

在没有其余技术支持下,调配给一个过程的内存空间必定是间断的,如何分配内存给过程能力使得物理内存利用率更好?因为每个过程执行工夫不同,所以会有一些过程比拟早完结,也有一些过程开始得比拟晚。当给新的过程分配内存空间时,有些开释掉的内存空间比拟小,无奈利用,天然就造成了内存碎片。 1.1 内存碎片间断内存调配是指给过程调配一块不小于指定大小的间断物理内存。如图1所示,一开始先给3个过程别离调配了间断的物理内存,其中过程P1占地址空间0-2,过程P2占地址空间3-8,过程P3占地址空间9-14。而后过程P2被开释掉,此时若须要调配一个内存大小为10的过程,则过程2开释掉的内存空间无奈给新过程,造成了内存碎片,能够看出所谓的内存碎片其实是相对而言的。 <center>图1</center> 内存碎片分类: 内部碎片:已分配内存单元之间的未被应用的内存空间,例如过程P2所开释的内存外部碎片:调配单元外部的未被应用的内存,然而取决于调配单元是否须要取整。例如调配510内存空间,实际上只能调配512这种$2^n$大小的内存空间,这时候就有2个字节无奈利用,造成外部碎片,如图2所示的黄色块。 <center>图 2</center> 1.2 间断内存调配-动态内存调配间断的内存空间如何调配能力更好地进步内存利用率?依据过程指定一个大小可变的分区(块,内存块)称为动态内存调配,因为依据理论状况为过程找一块适合大小的内存块,大一点的过程天然也调配更大的内存块,小的过程调配小的内存块,所以就叫动态内存调配了。 当初假如有5个过程,占用内存状况如图3(左)所示,过程2和过程4完结后内存占用状况如图3(右)所示。 <center>图3</center> 因为要给新过程找个适合的内存块,首先得晓得哪些内存块是闲暇的,哪些是被配置,操作系统须要保护这样的一个数据结构。那又该如何给某个过程找到一个适合的内存块使得总体内存利用率更好呢,有几种策略。别离是最先匹配法,最佳匹配法还有最差匹配法。 最先匹配法:调配n个字节,应用第一个可用的比n大的闲暇块。举个栗子,图4(左)蓝色块示意为按地址排列的闲暇块,如果要分500B内存块给新过程 ,那么1K内存块会是第一个找到的比500B大的闲暇块,将其中的500B内存调配给新过程,新的被调配的内存块会退出被调配的列表中,并注明是哪个过程所应用,剩下的500K闲暇块更新到闲暇列表中去。调配后闲暇块如图4(b)所示。 <center>图4</center> 实现过程: 闲暇分区按地址排序调配过程中,从头往后找,寻找第一个适合的内存块,更新列表开释内存块时,查看是否可与邻近闲暇块合并,更新列表长处: 简略因为后面找到了就不再往后找了,所以高地址可能会保留着较大的内存块,不便前面更大的过程申请更大的内存块。毛病: 因为会把较大内存块分成几个小块,所以会留下内部碎片因为留下内部碎片,所以申请较大内存块时候会比较慢最佳匹配:调配n字节内存块时候,查找并应用大于n的最小内存块。举个栗子,还是如图4(左)所示,蓝色块示意为按地址排列的闲暇块,如果要给新过程调配2k字节的内存块,那么将会找到最初那个3k内存块,并调配2k被新过程,同时并更新被调配和空间内存的列表。 实现过程如下所示: 闲暇分区从小到大排序调配时,查找一个适合的分区,更新列表开释内存块时,查找并且合并邻近的闲暇区域(如果找到,邻近指的是地址邻近不是大小邻近,所以相比最先匹配简单一些),更新列表长处: 可防止的闲暇分区被拆分可缩小内部碎片大小绝对简略毛病: 开释内存块时较慢内部碎片容易产生很多无用的小碎片最差匹配:调配n字节,应用尺寸不小于n的最大闲暇内存块。举个栗子,还是如图4(左)所示,蓝色块示意为按地址排列的闲暇块,如果要给新过程调配2k字节的内存块,那么将会找到两头那个10k内存块,并调配2k被新过程,同时并更新被调配和空间内存的列表。 实现过程如下所示: 闲暇分区按从大到小排序调配选最大内存块开释内存块时,查看是否可与邻近的闲暇块去进行合并,并调整闲暇内存块列表程序长处: 中等大小的内存块调配较多时,成果最好,因为剩下那内存块还能利用起来,相当于剩下的小块比拟少避免出现太多的碎片毛病 : 开释分区较慢内部碎片容易毁坏大的闲暇内存块,后续难以调配大的内存块# 3.物理内存治理-间断内存调配

October 26, 2021 · 1 min · jiezi

关于内存:第45问MySQL-的内存突增-该如何诊断

问在 第44问 中, 咱们应用 tcmalloc 提供的工具, 来查看 MySQL 的内存调配 该办法对性能影响不大, 能够在生产环境运行, 但须要将 MySQL 的分配器配置成 tcmalloc 在本次试验中, 咱们介绍另外一种办法, 针对于 MySQL 的内存突增状况进行诊断 试验咱们仍然宽油起一个数据库: 本试验中, 咱们须要模仿MySQL的内存突增的状况. 咱们从 MySQL 的 bug 库里找到一个易于复现的相干 bug: https://bugs.mysql.com/bug.ph... 这个 bug 的形容很清晰, 并提供了一个 SQL 脚本, 间接执行该脚本就能够复现内存激增的状况: 咱们来试一下: 以后 MySQL 的内存占用为181M 执行脚本: 在脚本执行过程中, 咱们会发现 MySQL 应用的内存在一直上涨 当初咱们来诊断 MySQL 对内存的应用. 在脚本执行过程中, 同时执行如下命令进行观测: 小贴士 什么是零碎调用mmap? 简略来说, MySQL不是间接向Linux申请内存, 而是向glibc申请内存. glibc会维持一个内存池, 当glibc发现内存池吃紧时, 会通过零碎调用mmap(或者brk)向Linux申请内存. 所以咱们监听系统调用mmap, 也就监听了MySQL在什么状况下须要大量内存 (即什么时候glibc的内存池吃紧了) ...

September 3, 2021 · 1 min · jiezi

关于内存:第44问MySQL-的内存消耗-有哪些不在-performanceschema-的统计范围

问当 MySQL 内存异样上涨, 咱们能够通过 performance_schema 察看内存的应用, 咱们在试验5中进行过介绍。 但咱们也会发现操作系统统计的 MySQL 内存用量比 performance_schema 统计的 MySQL 内存用量要多。 那么 MySQL 的内存耗费, 有哪些是不在 performance_schema 统计内的呢? 本期咱们设计试验来察看这个问题 试验咱们先装置 google-perftools: 装置后, 能够找到相干的库: 宽油起一个数据库: 记下数据库的启动参数, 并关掉数据库: 咱们在数据库启动命令前, 减少两个环境变量 LD_PRELOAD 和 HEAPPROFILE. 其中 LD_PRELOAD 指向方才咱们装置的 tcmalloc 库, HEAPPROFILE 是输入文件的门路. 启动数据库后, 咱们看到日志中输入了两个 heap 文件. 咱们在数据库中减少一些压力, 还是用咱们相熟的翻倍法: 多做点数据: 察看到输入了更多的 heap 文件: 上面咱们装置 pprof 来解析这些 heap 文件. 先下载 golang , 此步骤须要挂代理: ...

August 27, 2021 · 1 min · jiezi

关于内存:如何避免JS内存泄漏

简介: 很多开发者可能平时并不关怀本人保护的页面是否存在内存透露,起因可能是刚开始简略的页面内存透露的速度很迟缓,在造成重大卡顿之前可能就被用户刷新了,问题也就被暗藏了,然而随着页面越来越简单,尤其当你的页面是 SAP 形式交互时,内存透露的隐患便越来越重大,直到忽然有一天用户反馈说:“操作一会儿页面就卡住不动了,也不晓得为什么,以前不这样的呀”。这篇文章通过一些简略的例子介绍内存透露的考察办法、总结内存透露呈现的起因和常见状况,并针对每种状况总结如何防止内存透露。心愿能对大家有所帮忙。 作者 | 木及起源 | 阿里技术公众号 很多开发者可能平时并不关怀本人保护的页面是否存在内存透露,起因可能是刚开始简略的页面内存透露的速度很迟缓,在造成重大卡顿之前可能就被用户刷新了,问题也就被暗藏了,然而随着页面越来越简单,尤其当你的页面是 SAP 形式交互时,内存透露的隐患便越来越重大,直到忽然有一天用户反馈说:“操作一会儿页面就卡住不动了,也不晓得为什么,以前不这样的呀”。 这篇文章通过一些简略的例子介绍内存透露的考察办法、总结内存透露呈现的起因和常见状况,并针对每种状况总结如何防止内存透露。心愿能对大家有所帮忙。 一 一个简略的例子先看一个简略的例子,上面是这个例子对应的代码: 代码 1 代码 1 的逻辑很简略:点击“add date”按钮时会向 dateAry 数组中 push 3000 个 new Date 对象,点击“clear”按钮时将 dateAry 清空。很显著,“add date”操作会造成内存占用一直增长,如果将这个逻辑用在理论利用中便会造成内存透露(不思考成心将代码逻辑设计成这样的状况),上面咱们看一下如何考察这种内存增长呈现的起因以及如何找出内存透露点。 1 heap snapshot为了防止浏览器插件的烦扰,咱们在 chrome 中新建一个无痕窗口关上上述代码。而后在 chrome 的 devtools 中的 Memory 工具中找到 “Heap Snapshot”工具,点击左上角的录制按钮录制一个 Snapshot,而后点击“add date”按钮,在手动触发 GC(Garbage Collect)之后,再次录制一个 Snapshot,重复执行上述操作若干次,像图 1 中操作的那样,失去一系列的 Snapshot。 图 1 录制 Snapshot 图 2 是咱们刚刚失去的 Snapshot 组,其中的第一个是页面初始加载的时候录制的,不难发现,从第二个开始,每个 Snapshot 相比于上一个其大小都减少了约 200KB,咱们点击抉择 Snapshot 2,在 class filter 输入框中处输出 date,能够失去 Snapshot 2 中所有被 Date 结构器结构进去的 JS 对象,也就是 Date 对象,这里看到的结构器跟浏览器外部的实现无关,不用跟 JS 的对象对应。 ...

August 6, 2021 · 4 min · jiezi

关于内存:为您的设计选择正确的内存解决方案

内存被视为一种必要的技术,然而工厂自动化、主动驾驶汽车、便携式医疗设施、边缘计算和物联网传感器等新利用正在迫使性能要求发生变化。因而用于评估和抉择特定应用程序内存的规范也产生了变动。 NAND、NOR和FRAM在各种利用中都有不同的劣势。因为这些解决方案中的每一个都有针对特定指标应用程序的独特功能集,因而确定哪种类型的内存解决方案可为所需应用程序提供最佳性能和可靠性十分重要。数据中心、计算机和生产设施中的海量存储须要最高的密度和最低的每比特老本,通常由NAND闪存反对。嵌入式计算机存储启动代码和事务数据,通常在NORFlash中可用。数据记录器、传感器和边缘计算机在长时间内捕捉疾速变动的数据应用专门的技术,例如铁电RAM(FRAM)。 让咱们看看哪些内存与这些工作负载相匹配: NAND闪存NAND FLASH常见于数据中心、云服务器和生产设施中。它的高密度使其成为这些工作的现实抉择,并且因为更好的工艺和几何膨胀,技术失去了改良。每GB老本持续降落,读/写性能持续体现良好。然而这种解决方案也存在肯定的局限性:每个编程/擦除周期都会对单元的小尺寸造成压力,从而升高其耐用性,并且尺寸也意味着大概10年的数据保留工夫低于其余内存解决方案。 NOR闪存NOR Flash具备用于保留长数据的大型存储单元和字节可寻址架构,因而非常适合用于疏导代码,其中包含就地执行零碎和事务数据。NOR牢靠且易于应用,其最新改良为故障安全操作提供性能平安和平安启动工具。对于汽车仪表盘和其余性能,NOR能够反对疾速读取和即时启动性能。然而NOR密度低于NAND。 FRAM内存FRAM非常适合须要通过应用较少的功率长时间间断捕捉数据的设施。存储单元交替极性,应用起码的能量来缩短电池寿命并提供近乎有限的耐用性。FRAM还打消了能量或电荷透露问题,因而数据保留至多能够继续100年。与广泛认识相同,FRAM不会被磁场烦扰;然而它的密度无奈反对编码和海量存储需要。 归结为:抉择适合的内存有助于确保产品的胜利。NAND闪存非常适合云计算和集体电子产品中常见的海量存储工作负载。相比之下,NOR Flash和FRAM实用于嵌入式零碎和边缘设施,它们通常位于极其和偏僻的环境中。随着边缘计算的倒退,人工智能的提高正在推动新性能的倒退,并进步对进步故障安全操作规范的需要,这反过来迫使制造商提供具备平安和安保性能的NOR Flash和FRAM。内存存储芯片供应商英尚微电子可提供产品相干技术支持.

July 27, 2021 · 1 min · jiezi

关于内存:OracleHugePage-Size-计算脚本

HugePage计算须要SGA等失效,须要先配置好内存 #!/bin/bash## hugepages_settings.sh## Linux bash script to compute values for the# recommended HugePages/HugeTLB configuration# on Oracle Linux## Note: This script does calculation for all shared memory# segments available when the script is run, no matter it# is an Oracle RDBMS shared memory segment or not.## This script is provided by Doc ID 401749.1 from My Oracle Support# http://support.oracle.com# Check for the kernel versionKERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'`# Find out the HugePage sizeHPG_SZ=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`if [ -z "$HPG_SZ" ];then echo "The hugepages may not be supported in the system where the script is being executed." exit 1fi# Initialize the counterNUM_PG=0# Cumulative number of pages required to handle the running shared memory segmentsfor SEG_BYTES in `ipcs -m | cut -c44-300 | awk '{print $1}' | grep "[0-9][0-9]*"`do MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q` if [ $MIN_PG -gt 0 ]; then NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q` fidoneRES_BYTES=`echo "$NUM_PG * $HPG_SZ * 1024" | bc -q`# An SGA less than 100MB does not make sense# Bail out if that is the caseif [ $RES_BYTES -lt 100000000 ]; then echo "***********" echo "** ERROR **" echo "***********" echo "Sorry! There are not enough total of shared memory segments allocated forHugePages configuration. HugePages can only be used for shared memory segmentsthat you can list by command: # ipcs -mof a size that can match an Oracle Database SGA. Please make sure that: * Oracle Database instance is up and running * Oracle Database 11g Automatic Memory Management (AMM) is not configured" exit 1fi# Finish with resultscase $KERN in '2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`; echo "vm.hugetlb_pool = $HUGETLB_POOL" ;; '2.6' | '3.8' | '3.10' | '4.1' | '4.14' | '4.18' | '5.4') echo "vm.nr_hugepages = $NUM_PG" ;; *) echo "Kernel version $KERN is not supported by this script (yet). Exiting." ;;esac# End

July 17, 2021 · 2 min · jiezi

关于内存:分布式-Prepare-Statement-协议游标可行性

作者:鲍凤其爱可生 dble 团队开发成员,次要负责 dble 需要开发,故障排查和社区问题解答。少说废话,放码过去。本文起源:原创投稿*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。背景MySQL JDBC 在执行查问语句时,默认把查问的所有后果全副取回放在内存中,如果遍历很大的表,则可能把内存撑爆。 方法 1查问语句中应用 limit,offset;这样咱们会发现取数据的越来越慢,起因是在设置了 offset 之后,MySQL 须要将读取地位挪动到 offset 的地位,随着 offset 增大,取数据也越来越慢; 方法 2用数据流的形式取数据,能够指定 fetch size,这样每次获取指定数量的数据行,从而防止 OOM。此种形式的应用形式和原理能够参见文章:prepare statement 协定第 2 种形式理论是 MySQL 中的 server-side 游标,server-side 游标是应用 MySQL 外部长期表来实现的。初始的时候,外部长期表是个内存表,当这个表的大小超过 max_heap_table_size and tmp_table_size 两个零碎变量的最小值的时候(两者的最小值),会被转换成 MyISAM 表,即落盘存储。外部长期表的应用限度同样实用于游标的外部长期表。 MySQL 中的两种长期表内部长期表用户通过 CREATE TEMPORARY TABLE 语句显式创立的长期表,这样的长期表称为内部长期表。内部长期表生命周期:创立后,只在以后会话中可见,以后会话完结的时候,该长期表也会被主动敞开。因而,两个会话能够存在同名的长期表,但若有同名的非长期表时,直到长期表被删除,这张表对用户是不可见的。 外部长期表外部长期表是一种非凡轻量级的长期表,用来进行性能优化。这种长期表会被 MySQL 主动创立并用来存储某些操作的两头后果。这些操作可能包含在优化阶段或者执行阶段。这种外部表对用户来说是不可见的,然而通过 EXPLAIN 或者 SHOW STATUS 能够查看 MySQL 是否应用了外部长期表用来帮忙实现某个操作。外部长期表在 SQL 语句的优化过程中扮演着十分重要的角色,MySQL 中的很多操作都要依赖于外部长期表来进行优化。然而应用外部长期表须要创立表以及两头数据的存取代价,所以用户在写 SQL 语句的时候应该尽量的去防止应用长期表。 外部长期表有两种类型1、HEAP 长期表这种长期表的所有数据都会存在内存中,对于这种表的操作不须要 IO 操作。 2、OnDisk 长期表顾名思义,这种长期表会将数据存储在磁盘上。OnDisk 长期表用来解决两头后果比拟大的操作。如果 HEAP 长期表存储的数据大于 MAX_HEAP_TABLE_SIZE(参数参考链接),HEAP 长期表会被主动转换成 OnDisk 长期表。OnDisk 长期表在 5.7 中能够通过 INTERNAL_TMP_DISK_STORAGE_ENGINE 零碎变量抉择应用 MyISAM 引擎或者 InnoDB 引擎。 ...

December 10, 2020 · 1 min · jiezi

关于内存:ram存储器基本概念

目前的铁路和电力及航空航天等多个行业已纷纷推广系统可靠性剖析RAM技术,研发最佳的设施运行保护计划,从而打消设施隐患,防止设施事变产生,升高安装非打算复工次数和设施运行维护费用,促成安装平安长周期运行,具备重要的现实意义。本文次要概括介绍RAM技术的基本概念。 ram为可靠性(Reliability)、可用性(Availability)、可维护性(Maintainability)的简称,是以可靠性实践为根底的延长和倒退.RAM通过对历史数据的回归或专家教训的总结,对故障产生的概率进行计算,从而量化危险,同时针对该危险而履行的监测、检测或检培修不同计划的优劣进行量化比拟,从而辅助管理层作出正确的决策。其相干概念简述如下: (1)可靠性,指某一时间段内设施或零碎间断运行而无故障产生的概率。重要表征参数是均匀无故障工夫(Mean Time Between Failure,简称MTBF)是指相邻两次故障之间的均匀工作工夫,也称均匀故障间隔时间。如图1所示MTBF= ,零碎故障率= 1/MTBF。 图1MTBF与MDT的含意及关系 (2) 可维护性,指随时间推移培修工作未实现的概率。重要表征参数是均匀修复工夫(Mean Time ToRepair,简称MTTR),包含诊断、组件修理与替换及现场调整与测试的工夫。零碎修复率u = 1/MTTR.均匀停机工夫(Mean Down Time,简称MDT)是将MTTR的定义扩大至包含经营及/或保护员工达到现场前的反应时间(Reaction Time,简称RT),是掂量培修效率的尺度,由均匀修理工夫与均匀等待时间组成。即MDT=MTTR +RT。如图1所示,MDT = 。 (3)可用性,指某一段时间内设施或零碎可失常运行的工夫百分比。可用性=运行工夫/(运行工夫+复工工夫)。零碎固有可用性(Inherent availability,简称IA) =MTBF/(MTBF+MTTR)。零碎经营可用性(Operational availability,简称OA)) =MTBF/(MDT+MTTR)。因为运行工夫受可靠性影响、复工工夫受可维护性影响,因而可用性由可靠性及可维护性决定,如图2所示。 图2故障率浴盆曲线

November 24, 2020 · 1 min · jiezi

关于内存:MRAM与其他内存技术相比具有相对优势

MRAM是一种非易失性存储技术,能够在不须要电源的状况下将其内容保留至多10年。它实用于在零碎解体期间须要保留数据的商业利用。基于MRAM的设施能够为“黑匣子”利用提供解决方案,因为它以SRAM的速度写入数据,同时在产生总功耗之前保留数据。Everspin一级代理英尚微电子本文介绍MRAM与其余内存技术的相比拟。 MRAM与内存 内存选项的比拟与其余内存技术选项相比,MRAM具备显著的劣势(下表1)。 表格1 MRAM与其余内存技术相比具备绝对劣势 Flash这项技术利用电荷存储在笼罩在栅极氧化物上的一块浮动多晶硅(浮动栅极)上。对闪存位单元进行编程须要一个高电压场,该场能使电子减速得足够快,以克服硅与浮栅之间的氧化物的能垒。 这导致电子穿透氧化物并为浮置栅极充电,从而扭转了位单元晶体管的阈值电压。电子通过氧化物的重复转移逐步使氧化物资料磨损,在位不再起作用之前,闪存被限度为10K-1M写周期。 间断写入会在10天之内耗尽一些闪存。同时因为不波及充电或放电,MRAM能够接受有限的写入周期。编程过程中会旋转磁极,这是一种无损且无损的操作。 在编程期间,闪光灯须要低压能力使电子穿过氧化物资料。MRAM应用产生磁场的电流来编程自在层。此外,闪存对存储器阵列的大块执行编程器擦除操作。MRAM在单个地址上执行写入。 SRAMSRAM应用放弃CMOS逻辑电平的有源晶体管,须要电源能力保留存储器内容。MRAM存储器的内容放弃在其自在磁性层的极性中。因为该层是磁性的,即便没有电源也能够放弃其状态。 随着技术一直缩小SRAM单元的体积,较小的几何器件往往会透露更多电流。对于单个单元来说,这种透露很小,然而当与存储设备中的数百万个单元相乘时,透露就变得很显著。随着技术的萎缩,这种影响无望放弃。鉴于MRAM的非易失性,能够在零碎中应用掉电技术以实现零电流透露。 电池供电的SRAM它由一个SRAM单元和一个包装在同一包装中的电池组成。该非易失性存储器应用电池电量来保留存储器内容。同时MRAM不须要电池来保留数据,并且以比电池后备SRAM更快的速度执行读/写操作。这样能够进步可靠性并打消与电池解决无关的环境问题。 EEPROM与MRAM相比,该独立存储器的编程速度要慢得多,并且写入循环能力无限。 NVSRAM也称为非易失性SRAM,它联合了SRAM和EEPROM性能。它会在断电时将数据从SRAM存储到EEPROM。然而数据传输十分慢,并且在数据传输期间须要大的内部电容器来放弃NVSRAM的电源。MRAM提供了更快的写入速度,能够在失常的零碎操作期间写入数据。 因而在掉电期间起码的数据传输是必须的。应用MRAM的应用程序也能够受害于平安写入存储器而无需应用大型内部电容器。 FRAM另一个非易失性RAM铁电RAM(FRAM)具备典型的小型阵列大小,范畴从4Kbit到1Mbit。阵列尺寸很小,因为该技术的可扩展性无限,无奈进一步放大位单元的尺寸。 没有这种可伸缩性限度,MRAM能够提供更大的内存阵列。而且MRAM的编程速度比FRAM快。一些FRAM具备无限的循环能力(例如100亿个循环)。他们还须要在读取后刷新存储器,因为该操作会毁坏正在读取的位单元的内容。 DRAM应用此技术,必须常常刷新内存以保留数据。

September 16, 2020 · 1 min · jiezi