跟谁学一面

自定义缓存设计方案(LRU)

常用缓存淘汰算法

内存的淘汰机制主要有以下几种:
1、FIFO (First In, First Out)
先进先出算法
2、LFU (Least Frequently Used)
最不经常使用算法
3、LRU (Least Recently Used)
最近最少使用算法

实现思路

链表+HashMap

  • 创建时设定链表的长度
  • 查询时直接查询HashMap
  • 新数据插入到链表头部;
  • 每当缓存命中(即缓存数据被访问),则将数据移到链表头部;
  • 当链表满的时候,将链表尾部的数据丢弃,同时删除HashMap中对应的数据。

**增强的LinkedHashMap

LinkedHashMap结构示意图

LinkedHashMap 构造方法

    public LinkedHashMap() {
        // 调用HashMap的构造方法,其实就是初始化Entry[] table
        super();
        // 这里是指是否基于访问排序,默认为false
        accessOrder = false;
    }
  • 设置accessOrder为true
  • 新加入的数据和最近访问的数据都会放到链表尾部
  • 当链表满的时候,将链表头部的数据丢弃

Sprint Cloud 组件的自定义实现

Feign

  1. Https的支持
  2. 实现本地访问K8s内的服务发现
  3. 自定义HttpMessageConverter,用于解决消息头部中Content-Type=text/plain;charset=UTF-8导致解码失败问题

Zuul

  1. 与数据库结合实现动态路由和访问过滤

Admin

  1. 重定向指标输出路径到公司监控平台

其他

  1. 结合Apollo配置中心实现配置实时更新
  2. 结合使用场景实现大量默认配置,尽量减少配置数量
  3. 自定义骨架,降低模块创建成本

堆外内存的管理

堆外内存有什么优势?

减少垃圾回收:因为垃圾回收会对其他的应用产生影响
加快了复制的速度:堆内在flush到远程时,会先复制到直接内存(非堆内存),然后再发送;而存储在堆外内存相当于省略掉了这个工作
可以扩展至更大的内存空间。比如超过1TB甚至比主存还大的空间;

使用堆外内存的缺点

堆外内存的缺点就是内存难以控制,使用了堆外内存就间接失去了JVM管理内存的可行性,需要自己管理,当发生内存溢出时排查起来非常困难。

申请堆外内存

# 方法一(推荐)
ByteBuffer.allocateDirect(10 * 1024 * 1024)
# 方法二(不推荐)
unsafe.allocateMemory(size)

堆外内存回收

参考:JVM——堆外内存详解

JDK中使用DirectByteBuffer对象来表示堆外内存,每个DirectByteBuffer对象在初始化时,都会创建一个对应的Cleaner对象,这个Cleaner对象会在合适的时候执行unsafe.freeMemory(address),从而回收这块堆外内存。

当初始化一块堆外内存时,对象的引用关系如下:


image

其中firstCleaner的静态变量,Cleaner对象在初始化时会被添加到Clener链表中,和first形成引用关系,ReferenceQueue是用来保存需要回收的Cleaner对象。

如果该DirectByteBuffer对象在一次GC中被回收了,即

image

此时,只有Cleaner对象唯一保存了堆外内存的数据(开始地址、大小和容量),在下一次FGC时,把该Cleaner对象放入到ReferenceQueue中,并触发clean方法。

Cleaner对象的clean方法主要有两个作用:

  1. 把自身从Cleaner链表删除,从而在下次GC时能够被回收
  2. 释放堆外内存

在初始化DirectByteBuffer对象时,会自动去判断,如果堆外内存的环境很友好,那么就申请堆外内存;如果当前堆外内存的条件很苛刻时(即有很多无效内存没有得到释放),这时候就会主动调用System.gc()强制执行FGC,从而释放那些无效内存。

为了避免这种悲剧的发生,也可以通过-XX:MaxDirectMemorySize来指定最大的堆外内存大小,当使用达到了阈值的时候将调用System.gc来做一次full gc,以此来回收掉没有被使用的堆外内存。

两个线程交叉打印1和2

// 打印线程
public class Printer implements Runnable {
    private String val;
    private AtomicBoolean flag;
    private boolean targetFlag;

    public Printer(String _val, AtomicBoolean _flag, boolean _targetFlag) {
        this.val = _val;
        this.flag = _flag;
        this.targetFlag = _targetFlag;
    }

    @Override
    public void run() {
        while(true) {
            boolean currentFlag = this.flag.get();
            if(currentFlag == this.targetFlag) {
                synchorized(Printer.class) {
                    if(currentFlag == this.targetFlag) {
                        System.out.println(this.val);
                        // flag 置成相反的值
                        this.flag.set(!currentFlag);
                    }
                }
            }
        }
    }
}



// 主线程
public class Main{
    private static AtomicBoolean flag = new AtomicBoolean(false);

    public static void main(String[] args) {
       Thread printer1 = new Thread(new Printer("1", flag, false));
       Thread printer2 = new Thread(new Printer("2", flag, true));
       printer1.start();
       printer2.start();
       Thread.currentThread().join();
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容

  • 带着问题,看源码针对性会更强一点、印象会更深刻、并且效果也会更好。所以我先卖个关子,提两个问题(没准下次跳槽时就被...
    Java李太白阅读 242评论 0 1
  • 上篇文章介绍了Netty内存模型原理,由于Netty在使用不当会导致堆外内存泄漏,网上关于这方面的资料比较少,所以...
    caison阅读 1,312评论 3 3
  • 原文:https://www.jianshu.com/p/35cf0f348275[https://www.jia...
    myf008阅读 324评论 0 0
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,535评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,187评论 4 8