cpu缓存

缓存有那么多种,分别是干什么的?

不问归期 提交于 2019-11-26 13:44:20
只要是位正儿八经的程序员应该都知道“缓存”是什么,甚至我司的很多做运营的小姐姐现在和程序员小哥哥交流中都时不时冒出“缓存”这个词,让人压力山大。 当然,这里讨论的是指软件层面的缓存。大家都知道的一点是,缓存可以让原本打开很慢的页面,变得能“秒开”。你平时访问的 APP 与网站几乎都有涉及到缓存的运用。 那么,缓存除了能加速数据的访问之外,还有什么作用呢? 另外,任何事物都有两面性,我们如何才能将缓存的优点发挥得淋淋尽致,同时避免掉到它的弊端中呢? 本文接下来就给大家分享一下如何理解缓存,以及它的运用思路,希望对你有所启发。 缓存能做什么? 正如前面所说,大家最普遍的理解就是当我们遇到某个页面打开很慢的时候,会想到引入缓存,这样页面打开就快了。 其实快和慢都是相对的,从技术角度来说,缓存之所以快是因为缓存是基于内存去建立的,而内存的读写速度比硬盘快 X 倍,所以用内存来代替硬盘作为读写的介质自然能大大提高访问数据的速度。 这个过程大致是这样的,通过在内存中存储被访问过的数据供后续访问时使用,以此来达到提速的效果。 其实除此之外,缓存还有另外 2 个重要的运用方式:预读取和延迟写。 预读取 预读取就是预先读取将要载入的数据,也可以称作“缓存预热”,它是在系统中先将硬盘中的一部分数据加载到内存中,然后再对外提供服务。 为什么要这样做呢?因为有些系统一旦启动就要面临上千上万的请求进来

java架构之路(一)JMM和volatile关键字

隐身守侯 提交于 2019-11-26 12:45:55
  说到JMM大家一定很陌生,被我们所熟知的一定是jvm虚拟机,而我们今天讲的JMM和JVM虚拟机没有半毛钱关系,千万不要把JMM的任何事情联想到JVM,把JMM当做一个完全新的事物去理解和认识。 我们先看一下计算机的理论模型,也是冯诺依曼计算机模型,先来张图。 其实我们更关注与计算机的内部CPU的计算和内存之间的关系。我们在来深入的看一下是如何计算的。 我们来看一下这个玩意的处理流程啊,当我们的数据和方法加载的内存区,需要处理时,内存将数据和方法传递到CPU的L3->L2->L1然后再进入到CPU进行计算,然后再由L1->L2->L3->再返回到主内存中,但是我们的科技反展的很快的,现在貌似没有单核的CPU了吧,什么8核16核的CPU随处可见,我们这里只的CPU只是CPU的一个核来计算这些玩意。假设我们的方法是f(x) = x + 1,我们入参是1,期望得到结果是2,1+1=2,我计算的没错吧。如果我们两个核同时执行该方法呢?我们的CPU2反应稍微慢了一点呢?假如当我们的内存再向CPU2发送参数时,可能CPU1已经计算完成并且已经返回了。这时CPU2取得的参数就是2,这时再进行计算就是2+1了。结果并不是我们期望的结果。这其实就是数据未同步造成的。我们应该想尽我们的办法去同步一下数据。    我们中间加了一层缓存一致性协议。也就是我们的MESI,在多处理器系统中

70%的Java程序员不知道为啥 ConcurrentHashMap 读操作不需要加锁?

有些话、适合烂在心里 提交于 2019-11-26 03:08:25
作者:上帝爱吃苹果 目录 1.ConcurrentHashMap的简介 2.get操作源码 3.volatile登场 4.是加在数组上的volatile吗? 5.用volatile修饰的Node 6.总结 我们知道,ConcurrentHashmap(1.8)这个并发集合框架是线程安全的,当你看到源码的get操作时,会发现get操作全程是没有加任何锁的,这也是这篇博文讨论的问题——为什么它不需要加锁呢? ConcurrentHashMap的简介 我想有基础的同学知道在jdk1.7中是采用Segment + HashEntry + ReentrantLock的方式进行实现的,而1.8中放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现。 JDK1.8的实现降低锁的粒度,JDK1.7版本锁的粒度是基于Segment的,包含多个HashEntry,而JDK1.8锁的粒度就是HashEntry(首节点) JDK1.8版本的数据结构变得更加简单,使得操作也更加清晰流畅,因为已经使用synchronized来进行同步,所以不需要分段锁的概念,也就不需要Segment这种数据结构了,由于粒度的降低,实现的复杂度也增加了 JDK1.8使用红黑树来优化链表,基于长度很长的链表的遍历是一个很漫长的过程,而红黑树的遍历效率是很快的

缓存雪崩 缓存穿透

守給你的承諾、 提交于 2019-11-25 23:59:29
1,什么叫缓存雪崩 由于缓存失效,大量的访问直接去访问数据库,对数据库和CPU造成巨大的压力,严重的会造成数据库的宕机,系统崩溃。 2,如何防止缓存雪崩 1,缓存雪崩造成的直接原因,是由于同一时刻大量的缓存同时失效,所以大量的访问可能都没有从缓存中获得数据,从而访问数据库了。 可以让不同的key,设置不同的缓存时间,让缓存的失效时间分布的均匀点。 缺点,开发的时候比较麻烦,你开发的这个功能,还得问别人的开发功能的缓存的失效时间 2,可以用锁 对于数据库的访问,每次只能1个线程进行访问 缺点:治标不治本,性能差,只是减少了数据库的访问压力 3,消息中间件 用消息中间件的方式,和加锁的方式比较像,消息中间间可以相当于一个缓存队列,每次访问数据库的线程相对于加锁要多一点,性能要好 4,通过一级加二级缓存的方式 一级里面查询不到,到二级里面去查询。 做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期(此点为补充) 3,什么叫缓存穿透 缓存穿透就是,每次访问缓存的时候,没有访问到,然后去访问数据库,数据库也没有,多个类似的请求的时候,就会对数据库造成很大压力。 这种情况,黑客进行攻击的时候会出现 解决办法:如果数据库也没有,返回空,放入到缓存中,下次查询就不会访问数据库了,会减少数据库的压力。 private String

【并发那些事】可见性问题的万恶之源

时光总嘲笑我的痴心妄想 提交于 2019-11-25 21:59:15
【并发那些事】可见性问题的万恶之源 硬件工程师为均衡 CPU 与 缓存之间的速度差异,特意加的 CPU 缓存,竟然在多核的场景下阴差阳错的成为了并发可见性问题的万恶之源!( 本文过长,如果不是特别无聊,看到这里就可以了 ) 前言 还记得那些年,你写的那些多线程 BUG 吗?明明只想得到个 1 + 1 = 2 的预期,结果他有时候得到 1,有时候得到 3,但偏偏有时候他也会返回正确的 2。明明在本地运行的好好的,一上线一堆诡异的 BUG。你一遍一遍的检查代码,一行一行 debug,结果无功而返。 变量为何突然变异?代码为何乱序运行?条件为何形同虚设?欢迎收看今天的《走进科学》之半夜。。。哦,不对,欢迎阅读今天的《并发那些事》之可见性问题的万恶之源。就像上面说的,我们在写并发程序时,经常会出现超出我们认识与直觉的问题,而按我们的以往的经验,很难去察觉到他的问题所在。而又因为我们不了解他发生的诱因,即使我们按照书上的方案解决了,但是下次还是会出现。所以本文的主旨并不是解决问题的术,而是解决问题的道。一起来探究多线程问题的根源。 首先揭开谜底,大多数并发问题的发生都是这三个问题导致的, 可见性问题、原子性问题、有序性问题 。那么又是什么导致这三个问题的出现呢?本文将一步步解析可见性问题出现的原因。 核心矛盾 众所周知,电脑由很多的部件组成。其中最最最重要的有三个,它们分别是 CPU 、内存