AmmoMercy的技术博客

Stay hungry, stay foolish.

0%

在2021年的今天,RSS其实是一种很小众的信息获取方式。但是It’s pretty cool~话不多说进入正题

其实RSS本质上是一种存放在服务器上的xml文件,我们只需用hexo-generator-feed生成xml文件即可。

首先使用node install hexo-generator-feed安装插件

然后在hexo的根目录下添加配置配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
feed:
enable: true
type: atom
path: atom.xml
limit: 10
hub:
content: true
content_limit:
content_limit_delim: ' '
order_by: -date
icon: icon.png
autodiscovery: true
template:

配置含义

  • path - Feed 的路径. 当两种feed方式(atom和RSS2)都配置时,path也需要配置 (默认: atom.xml/rss2.xml)
  • limit - feed一次性最多读取几篇 ( 0 / false代表全部读取 )
  • hub - PubSubHubbub的地址
  • content - 为true feed中会包含整篇文章
  • content_limit -文章长度限制 默认为summary的长度
  • order_by - Feed 的排序
  • icon - icon

配置完毕,hexo clean&&g 生成即可

Reinforcement learning-driven address mapping and caching for flash-based remote sensing image processing

Introduction

  • 遥感等地球观测技术生成的图像数据量很大,传统地面站计算方式信息传输量大,计算工作下沉到在轨设备是一种新的趋势。(类似雾计算的概念?)

  • 对I/O要求高,遂使用Flash作为数据存储。

  • Flash特性决定采用异地更新策略。

  • FTL在控制器实现,作用是提供地址转换。

  • 粒度划分的映射策略:page映射、block映射以及混合映射,本文采用page映射

  • 遥感图像处理有其独特的I/O特征、需要高吞吐量以及限制SRAM大小

    • 张提出基于可能性的缓存管理策略——灵活性差——可通过机器学习改进
    • 强空间局部性和相关的访问模式
    • 访问序列是一些小的随机访问的多次重复

2.1cache替换

  • f-lash cache替换的特殊特质:

    • 脏页写回
    • 逻辑-物理映射键值对多而SRAM容量小——内部SRAM存储部分常用映射(LRU)
  • 将cache分成不同的区域并使用不同的替换策略:如CF LRU分成两个区域working/clean-first只在cf中进行cache回收

  • 非冷脏优先存储or热干净优先=>无普适方法

  • 本文关注映射而不是实际数据

2.3强化学习

  • agent 动态随机environment 长期奖励

  • agent根据来自不同环境的reward学习

  • reward源于agent的action

Visual analysis

  • 遥感图形处理io trace视觉分析说明有更明显的访问模式:

    • 连续读写带来的强空间局部性
    • 不经常重复度- 弱时间局部性
    • 大的io请求更好的连续性模式 更弱的时间局部性
    • 时空局部性随时间改变

    res:现有的cache替换算法很难适用于这种特定模式

  • 小io:

    • logs 写
    • metadata图像元数据(时间、格式、地理信息等)读
  • 大io:图像本身

  • 大io有好的访问模式和空间局部性 但大io仍然可再分 不能简单地使用粗粒度的调度

  • 现有的调度算法是content-blind 与内容无关的

  • 几种关注内容的ftl

    • SFTL 基于bitmap 适用性差
    • CDFTL 两级按需缓存->冗余 为高度规则的io模式设计
  • 调度策略:

    • 大小分开
    • 读写分开
    • 适应性好
    • 总体性能 而非单纯的命中率
    • Q-FTL

Methodology

  • 实时 遥感数据处理 缓存容量有限
  • 总体性能 应用时间局部性 消耗评估 缓存管理技术
  • 尽可能减少写脏映射 同时提升命中率
  • 视作序列预测问题 并用强化学习解决

4.1 overview

  • 大小分开
  • 动态权重计算
  • 强化学习替换算法
  • SRAM两个区域:
    • 小元数据:CFLRU
    • 大真正的图像数据:增强学习进行动态权重计算

4.2 Workflow of cache management

  • 翻译成逻辑地址:
    • 命中
    • 不命中:启动替换算法
  • 根据预定义的大小阈值分流请求
    • 超过阈值:page-level
    • 未超阈值:entry-level
  • page-level
    • 命中
    • 未命中:从entry-level
      • 空间足够
      • 空间不足:使用动态评价模型替换
        • 无脏数据
        • 有脏数据:写回
  • entry-level
    • 使用cf-clean
    • entry对应的页也在内存中:同时清理
    • 属于同一页的脏entry一起协会、
  • CF-LRU:干净的entry比更优先替换,脏entry被保留更久

4.3 Seperating large and small I/O requests

4.4. A weighting access cost measurement model

  • 独立请求

$$
Co𝑠𝑡t = {W_w\Sigma^1{k=0}W_k+W_r\Sigma^n_{k=0}R_k \over N}
$$

cost_t代表时间间隔t内的cost

W_w、W_r代表读写权重n是一个页内的entry数W_k和R_k代表当前页的第k个entry

4.5. Reinforcement learning-driven cache replacement

  • 低cost的页被优先替换

  • 使用强化学习来决定写和读相对权重

  • Q-learning 专注于长期最优解

  • 性能和额外开销的平衡

  • 强化学习的实现

    • agent与cahe flash和io请求交互
    • cache等构成env
    • actions为cost的比率w 实数且一位小数 而非直接将替换行为作为action
    • w∈[1,13)
      • w<1: r比w开销大
    • State被定义为基于eq1计算的开销
    • 权重w由强化学习实时调整

    由于数据量会变得很大 在一定时间间隔后将命中/未命中数据一分为二

在部署hexo时,出现了如下报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
INFO  Deploying: git
INFO Clearing .deploy_git folder...
INFO Copying files from public folder...
FATAL Something's wrong. Maybe you can find the solution here: https://hexo.io/docs/troubleshooting.html
TypeError [ERR_INVALID_ARG_TYPE]: The "mode" argument must be integer. Received an instance of Object
at copyFile (fs.js:1972:10)
at tryCatcher (D:\docs\blog\node_modules\bluebird\js\release\util.js:16:23)
at ret (eval at makeNodePromisifiedEval (D:\docs\npm_modules\node_modules\hexo-cli\node_modules\bluebird\js\release\promisify.js:184:12), <anonymous>:13:39)
at D:\docs\blog\node_modules\hexo-fs\lib\fs.js:144:39
at tryCatcher (D:\docs\blog\node_modules\bluebird\js\release\util.js:16:23)
at Promise._settlePromiseFromHandler (D:\docs\blog\node_modules\bluebird\js\release\promise.js:547:31)
at Promise._settlePromise (D:\docs\blog\node_modules\bluebird\js\release\promise.js:604:18)
at Promise._settlePromise0 (D:\docs\blog\node_modules\bluebird\js\release\promise.js:649:10)
at Promise._settlePromises (D:\docs\blog\node_modules\bluebird\js\release\promise.js:729:18)
at Promise._fulfill (D:\docs\blog\node_modules\bluebird\js\release\promise.js:673:18)
at Promise._resolveCallback (D:\docs\blog\node_modules\bluebird\js\release\promise.js:466:57)
at Promise._settlePromiseFromHandler (D:\docs\blog\node_modules\bluebird\js\release\promise.js:559:17)
at Promise._settlePromise (D:\docs\blog\node_modules\bluebird\js\release\promise.js:604:18)
at Promise._settlePromise0 (D:\docs\blog\node_modules\bluebird\js\release\promise.js:649:10)
at Promise._settlePromises (D:\docs\blog\node_modules\bluebird\js\release\promise.js:729:18)
at Promise._fulfill (D:\docs\blog\node_modules\bluebird\js\release\promise.js:673:18)
at Promise._resolveCallback (D:\docs\blog\node_modules\bluebird\js\release\promise.js:466:57)
at Promise._settlePromiseFromHandler (D:\docs\blog\node_modules\bluebird\js\release\promise.js:559:17)
at Promise._settlePromise (D:\docs\blog\node_modules\bluebird\js\release\promise.js:604:18)
at Promise._settlePromise0 (D:\docs\blog\node_modules\bluebird\js\release\promise.js:649:10)
at Promise._settlePromises (D:\docs\blog\node_modules\bluebird\js\release\promise.js:729:18)
at Promise._fulfill (D:\docs\blog\node_modules\bluebird\js\release\promise.js:673:18)

查询资料可知 是由于node.js@14+与hexo不兼容导致的(该bug 在2020年五月就已出现 截至2021.03仍未修复 李在赣神魔hexo)

遂降级node

点击node realease查看所有版本 我选择下载13.14

下载后直接解压至node所在目录 全部替换即可

水文完毕(逃

深入理解JVM笔记2

主要内存区域

程序计数器PC

与计算机硬件中的PC类似用于指示当前线程运行到的字节码指令的地址,当运行本地方法时,pc为undefined。

唯一一个没有规定OutOfMemoryError的区域。

虚拟机栈

线程私有,用于存放当前线程的方法栈帧。 栈帧是由局部变量表、操作数栈、动态链接以及方法出口等组成。

其中局部变量表不仅包含局部变量(基本类型直接存值,对象类型存引用)还包括了returnAddress(用于指示该方法完成后返回的字节码指令地址)。局部变量表的大小在编译之后就确定了,在方法的运行期间是不会改变的。比如一个int变量只可能存放int,对象的引用只能存放该对象类型的引用,自然不会变化。

本地方法栈

与虚拟机栈类似,只不过存放的是本地方法。所以,HotSpot虚拟机将其与虚拟机栈直接合二为一。

JAVA堆

又叫GC堆,几乎所有对象分配的场所,是JVM中最大的一块内存。之所以说是几乎所有,是因为当前JIT和逃逸分析技术的成熟,比如栈上分配和标量替换优化技术,使得对象不一定在堆上分配。堆由GC管理(见下一章GC)。

线程私有,但可以为了快速释放和分配内存而为每个线程分配私有的缓冲区(Thread Local Allocattion Buffer, TLAB)。

分为新生代、老年代。

新生代:有from survivor、to survivor、 eden。两个survivor用于存放young gc之后存活的对象,eden用于存放新生成的对象。因为大多数对象存活时间都很短,即所谓的“朝生夕死”,所以eden的容量较大,survivor空间较小。默认配置下from to各占1/10,eden占8/10。

堆的空间一般都是自动扩展的,通过-Xms和-Xmx两个参数来控制堆的最小和最大容量,当最大和最小容量设为相同值时,就变成了固定大小。

方法区

存放类的信息,逻辑上是堆的一部分。堆上存放对象,对象来自于类,两者十分相似,所以将方法区描述为堆的一部分是很自然的。在HotSpot上,对方法区的回收机制与堆类似,故其又称为永久代。不过在JDK1.8中,方法区被从堆中移到了直接内存里,永久代也不复存在了,取而代之的是元空间。

运行时常量池

方法区的一部分,存放编译期生成的各种常量。jdk1.8在物理实现上将其从方法区移出,存放在堆上单独开辟的空间,但逻辑上仍然是方法区的一部分。

直接内存

NIO利用该区域进行I/O,其在堆中有一个DirectByteBuffer对象,在该对象中存有直接内存的引用。使用直接内存的好处是可以避免在JAVA堆和Native堆中来回复制。

小结

上述所有区域中,只有pc没有OutOfMemory异常(毕竟只是一个记录执行位置的指针),其他区域都有可能产尘OutOfMemory异常。同时,对于虚拟机栈和本地方法栈来说,两个区域还会产生StackOverflow异常

线程私有 线程共享
pc、栈 堆、方法区

对象的创建

检查类是否被加载

对象的创建依赖于类的信息,所以在创建一个对象之前应该先确定该对象的类是否已经被加载到jvm。具体实现是检查常量池中是否包含类的引用。

分配内存

在堆上的空闲区为一个对象开辟一块区域。所以就必须要有空闲区进行管理的方法。一种方法是将已分配的空间集中在一侧,空闲区集中在另一侧(这种情况称为规整的),这样每次分配空间的时候将空闲区靠近分界的区域分配给新创建的内存即可。同时,利用一个指针来指示两个区域的分界,这种方法称为指针碰撞法。如果空闲内存和已使用的内存是交错的(即不规整),那么要维护一个列表来记录每个空闲块的地址和大小等信息,这种方法称为空闲链表法。

线程安全

对象的创建是十分频繁的,那么就需要进行一些操作来确保对象的分配是线程安全的。一是使用CAS加上失败重试来进行同步。另一种方法是使用TLAB,每个线程均在自己的TLAB中新建对象, 只有TLAB满了之后申请新的TLAB时,才需要同步锁定。

初始化

将分配到的内存空间设为零值(int是0,对象是null等),如果使用TLAB也可提前至TLAB进行。

一些设置

将一些必要的信息写入对象,如hashcode、分代年龄、类信息等。

对象的内存布局

对象头

两部分组成。第一部分用于存储对象本身的信息,如hashcode、分代年龄、与锁相关的一些信息等,也叫Mark Word。第二部分是只想该对象所属的类的指针。

对象字段

对象中定义的字段等。

对齐填充

jvm规定对象的长度必须是8字节的整数倍,如果前两项大小加起来不是8字节整数倍就需要进行填充。

其他

对象的访问

使用对象时需获取它的类型信息,那么如何获取呢?有两种方法:一种是利用在前面说过的,对象头的第二部分指向了对象所属的类,直接利用这个指针就可以,这被成为直接指针方法。另一种是维护一个句柄,句柄中有两项内容,一项是指向对象的指针,另一项是指向对象所对应的类的指针。

在栈帧中的局部变量表中,如果使用第一种方法,那么引用是直接指向对象的指针,而第二种方法的则指向句柄。

0.概念

JVM

JAVA编译产生字节码,字节码运行于JVM之上。使用JVM的好处:一是“一次编写到处运行”,只要统一虚拟机标准将底层操作系统与硬件封装,字节码的运行就可以无视操作系统和指令集平台,但是到现在看起来使离这个目标越来越远了。二是可以替程序员进行诸如内存分配、垃圾收集等工作,使程序员专注于项目开发。

jdk

jvm+JAVA API类库+JAVA语言本身

是用来开发最小环境,我们一般都认为

JRE

jre=jvm+SE api

用来运行的标准环境

1.JAVA发展史关键节点

Sun开发了JDK1.0以及第一个JVM Sun classic VM

Longview tech开发了鼎鼎有名的Hotspot的前身 ,后该公司被Sun收购,之后Hotspot在JDK1.2中作为附加程序发布,JDK1.3之后作为默认虚拟机发布。

JDK1.6 后Sun宣布在GPL v2下开源JDK,开源项目名为Open JDK,其与SUN JDK基本无异。

JDK1.7因为种种原因“缩水+跳票”,同时Oracle收购了Sun。而在此之前Oracle收购了BEA,至此Oracle拥有了三大虚拟机中的两个:HotSpot和JRockit。

2.几款重要的虚拟机

Classic VM

第一款JAVA虚拟机,纯解释运行。如果想编译运行,需要外挂Sun wjit等编译器,这时就变成了纯编译运行。这就导致他的效率很低,JAVA很慢的刻板印象也从此而来。其从JDK1.0到JDK1.2都是默认的虚拟机。

Exact VM

所谓的Exact是指准确式内存管理,即在虚拟机里有专门的数据结构来记录哪个内存位置存放了引用,以便在更改和回收对象时确定到底哪里是引用。同时这个虚拟机有两级即时编译器和编译器与解释器混合工作等现代高性能虚拟机的雏形。但其只来得及发布Solaris版本就被HotSpot取代了。

HopSpot VM

Hotspot命名源于其热点代码探测技术,即根据执行计数器找到代码执行的“热点”,如循环,多次调用的方法等,对其进行编译。是现在使用范围最广泛的虚拟机。

3.展望未来

这里的未来也可以看作JDK1.7“缩水”的内容(误

模块化

参见:https://zhuanlan.zhihu.com/p/24800180

混合语言

在JVM上运行别的语言,但这些语言需要额外的JVM实现版本,如JS在JVM的实现版本Rhino。

并行

在CPU核心数越来越多的今天,JDK8引入函数式编程这一天生就适合多核并行的编程方式,有效地为JAVA注入了新的生命。同时,为了利用显卡的算力,Open JDK还有一个Sumatra项目。以及在集群方面,还有Apache的Hadoop等等项目,不再赘述。

64位虚拟机

在机器平台逐渐由32位向64位过渡的今天,JVM也有了64位的版本,尽管现在性能并不尽人意,但总归会过渡到64位平台。

this指代当前对象 可以用来放回当前对象或者在构造器中调用其他构造器

static方法/成员变量可以通过对象访问 但不推荐

条件表达式只能出现布尔值(不能像c++一样出现int 1或0)

默认equeals比较引用相当于== 如果想比较内容应重写该方法

int 溢出不会出现异常

Math.random() 返回[0,1)Double 值

在找不到接受char的方法时 char会提升至int

传参自动升级 手动降级

确定方法的标识符是id、参数和参数顺序(不推荐) 返回值不同不能构成重载

可变参数列表提供了“可选”参数的功能 但实际上还是个数组 而且会导致重载混乱的问题(不推荐)

子类对象包括一个父类对象 而且父类对象先创建 super()显示调用构造器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class grandfather{
public grandfather() {
System.out.println("grand");
}
}
class father extends grandfather{
public father() {
System.out.println("father");
}
}
public class child extends father{
public child() {
System.out.println("child");
}

public static void main(String[] args) {
new child();
}
}


输出结果

1
2
3
grand
father
child

0. 为什么要关闭动画?

研究表明,人们可以检测到延迟仅为1/10秒,仅仅1秒钟的延迟就足以打断一个人的自觉思维过程,几秒钟的延迟会严重损害网站用户的体验。当在google搜索到有关内容打开时,不到1s的动画也是令人难以忍受的。我相信,有许多人像我一样对next主题的默认动画深恶痛绝。

阅读全文 »