guava-retrying

guava-retrying http://blog.csdn.net/aitangyong/article/details/53840719 https://github.com/rholder/guava-retrying 对于开发过网络应用程序的程序员来说,重试并不陌生,由于网络的拥堵和波动,此刻不能访问服务的请求,也许过一小段时间就可以正常访问了。比如下面这段给某个手机号发SMS的伪代码: // 发送SMS public boolean sendSMS(String phone, String content) { int retryTimes = 3; for(int i=0; i<=3; i++) { try { boolean result = doSomething(phone, content); // 发送成功直接返回 if(result == true) { return true; } } catch(IOException e) { // 可能是网络问题导致IOException,所以我们继续重试 logger.error("send sms error", e); } catch(Exception e) { // 未知异常,与网络无关,有可能是代码出现问题,这个时候重试没用,我们直接返回false logger.error("unknown exception", e); return false; } } return false; } // 给某人发短信 private boolean doSomething(String phone, String content) { } 这段代码有什么问题呢?看起来很丑,为了实现重试逻辑,各种if-else,各种try-catch。重试逻辑太简单,只是控制了重试次数,并没有控制2次重试之间的时间间隔。因为重试代码与业务代码耦合在一起,所以看起来很复杂。 ...

2017-07-20 · 1 min · 150 words · -

ntp, chrony, 时钟服务, 时钟同步

systemd-timesyncd, ntp, chrony NTP,是 Net Time Protocol 的缩写,意即网络时间协议。 archlinux 默认启用 ntp systemd-timesyncd archinstall 默认使用 systemd-timesyncd 作时钟同步, UDP 123 端口(NTP 协议),不能用 https 代理 systemd-timesyncd 是一个用于跨网络同步系统时钟的守护服务。它实现了一个 SNTP 客户端。与NTP的复杂实现相比,这个服务简单的多,它只专注于从远程服务器查询然后同步到本地时钟。 # archlinux 的时钟同步是默认启用的. timedatectl status # System clock synchronized: yes # 检查其状态 systemctl status systemd-timesyncd # systemd-timesyncd 服务启用 sudo systemctl enable systemd-timesyncd --now # timedatectl 层面启用 NTP sudo timedatectl set-ntp true # 禁用 sudo systemctl stop systemd-timesyncd sudo systemctl disable systemd-timesyncd sudo systemctl mask systemd-timesyncd sudo timedatectl set-ntp false chrony install # install chrony - arch sudo pacman -S chrony # for centos yum install chrony # ubuntu apt install chrony chrony 配置 # 号和 ! 号都代表注释 ...

2017-07-20 · 6 min · 1215 words · -

database schema

database schema 对于MySQL,schema和database可以理解为等价的. As defined in the MySQL Glossary:In MySQL, physically, a schema is synonymous with a database. You can substitute the keyword SCHEMA instead of DATABASE in MySQL SQL syntax, for example using CREATE SCHEMA instead of CREATE DATABASE.Some other database products draw a distinction. For example, in the Oracle Database product, a schema represents only a part of a database: the tables and other objects owned by a single user. ...

2017-07-18 · 1 min · 74 words · -

InfluxDB

InfluxDB 时间序列数据库 InfluxDB 基于 Go 语言开发,社区非常活跃,项目更新速度很快,日新月异,关注度高。 特点 可以设置metric的保存时间。 支持通过条件过滤以及正则表达式删除数据。 支持类似 sql 的语法。 可以设置数据在集群中的副本数。 支持定期采样数据,写入另外的measurement,方便分粒度存储数据。 概念 数据格式 Line Protocol measurement[,tag_key1=tag_value1…] field_key=field_value[,field_key2=field_value2] [timestamp] cpu_load,host_id=1 value=0.1 1434055562000000000 相比于 JSON 格式,无需序列化,更加高效。 measurement: metric name,例如 cpu_load。 field-key, field-value: 通常用来存储数据,类似 opentsdb 中的 value=0.6,但是支持各种类型,数据存储时不会进行索引,每条数据必须拥有一个 field-key,如果使用 field-key 进行过滤,需要遍历一遍所有数据。 tags-key, tags-value: 和 field-key 类似,但是会进行索引,方便查询时用于过滤条件。 Series measurement, tag set, retention policy 相同的数据集合算做一个 series。 假设 cpu_load 有两个 tags,host_id 和 name,host_id 的数量为 100,name 的数量为 200,则 series 基数为 100 * 200 = 20000。 ...

2017-07-12 · 3 min · 578 words · -

IntelliJ IDEA

IntelliJ IDEA IntelliJ IDEA Windows JBR是什么 https://www.4spaces.org/what-is-intellij-idea-jbr/embed/#?secret=ZFT4esKgN4 idea without JBR JBR是指JetBrains Runtime,JetBrains Runtime是一个运行时环境,用于在Windows,macOS和Linux上运行基于IntelliJ Platform的产品。 JetBrains Runtime基于OpenJDK项目并进行了一些修改。 这些修改包括: 亚像素抗锯齿(Subpixel Anti-Aliasing),Linux上的增强字体渲染,HiDPI支持,连字(ligatures),macOS上的 San Francisco 字体系列支持,官方构建中未提供的本机崩溃的一些修复,以及其他小的增强功能。 JetBrains Runtime与所有JetBrains IDE的最新版本捆绑在一起,默认情况下使用,除非执行显式重新配置。 例外是32位Linux系统,其中IDE需要单独的JDK安装,因为目前只捆绑了64位JetBrains Runtime。 对于Windows,捆绑了32位JetBrains Runtime,它可以在32位和64位系统上运行。 中文 IntelliJ IDEA是一个非常强大的IDE,但是只有英文版,且默认的中文显示有一定问题。本文介绍了IntelliJ IDEA 12.0中文显示问题解决方案。 IDE本身的中文乱码 这个问题体现在IDE本身,比如打开文件浏览目录的时候,中文名的文件或目录会显示成方块。 解决方法: 进入设置页。File->Settings。 进入IDE Settings里的File Encodings项,把IDE Encoding项设置成UTF-8。确定。 进入IDE Settings里的Appearance项,选中Override default fonts by,把Name设置为你喜欢的字体 (我使用的是Yahei Consolas Hybrid) ,Size根据自己喜好设置 (我一般设为 14) 。确定。 以上应该可以保证中文显示没有问题了。 编辑器的中文问题 这个问题体现在代码编辑区中写中文时,可能会乱码或者中文汉子全部重叠在一起。 首先要确定你正在编辑的文件是UTF-8编码的,有很多文件可能默认是ANSI编码。 至于中文重叠那是因为你所选用的默认中文字体不对,一直以来我写代码都是用的consolas,但是这个字体不支持中文,Intellij IDEA 12中如果使用默认的中文字体 (不知道是哪个字体) 就会重叠在一起,在网上找了好久,终于找到一个神一般的字体Yahei Consolas Hybrid,即微软雅黑和consolas的混合! 于是乎,File->Settings IDE Settings->Editor->Color & Fonts->Font,设置字体为Yahei Consolas Hybrid即可。 ...

2017-07-11 · 1 min · 88 words · -

HBase Compaction

HBase Compaction HBase Compaction的前生今世-身世之旅 2016年7月13日 范欣欣 HBase 了解HBase的童鞋都知道,HBase是一种Log-Structured Merge Tree架构模式,用户数据写入先写WAL,再写缓存,满足一定条件后缓存数据会执行flush操作真正落盘,形成一个数据文件HFile。随着数据写入不断增多,flush次数也会不断增多,进而HFile数据文件就会越来越多。然而,太多数据文件会导致数据查询IO次数增多,因此HBase尝试着不断对这些文件进行合并,这个合并过程称为Compaction。 Compaction会从一个region的一个store中选择一些hfile文件进行合并。合并说来原理很简单,先从这些待合并的数据文件中读出KeyValues,再按照由小到大排列后写入一个新的文件中。之后,这个新生成的文件就会取代之前待合并的所有文件对外提供服务。HBase根据合并规模将Compaction分为了两类: MinorCompaction和MajorCompaction Minor Compaction是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程中不会处理已经Deleted或Expired的Cell。一次Minor Compaction的结果是更少并且更大的StoreFile。 Major Compaction是指将所有的StoreFile合并成一个StoreFile,这个过程还会清理三类无意义数据: 被删除的数据、TTL过期数据、版本号超过设定版本号的数据。另外,一般情况下,Major Compaction时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此线上业务都会将关闭自动触发Major Compaction功能,改为手动在业务低峰期触发。 Compaction作用 | 副作用 上文提到,随着hfile文件数不断增多,一次查询就可能会需要越来越多的IO操作,延迟必然会越来越大,如下图一所示,随着数据写入不断增加,文件数不断增多,读取延时也在不断变大。而执行compaction会使得文件数基本稳定,进而IO Seek次数会比较稳定,延迟就会稳定在一定范围。然而,compaction操作重写文件会带来很大的带宽压力以及短时间IO压力。因此可以认为,Compaction就是使用短时间的IO消耗以及带宽消耗换取后续查询的低延迟。从图上来看,就是延迟有很大的毛刺,但总体趋势基本稳定不变,见下图二。 11 22 为了换取后续查询的低延迟,除了短时间的读放大之外,Compaction对写入也会有很大的影响。我们首先假设一个现象: 当写请求非常多,导致不断生成HFile,但compact的速度远远跟不上HFile生成的速度,这样就会使HFile的数量会越来越多,导致读性能急剧下降。为了避免这种情况,在HFile的数量过多的时候会限制写请求的速度: 在每次执行MemStore flush的操作前,如果HStore的HFile数超过hbase.hstore.blockingStoreFiles (默认7) ,则会阻塞flush操作hbase.hstore.blockingWaitTime时间,在这段时间内,如果compact操作使得HStore文件数下降到回这个值,则停止阻塞。另外阻塞超过时间后,也会恢复执行flush操作。这样做就可以有效地控制大量写请求的速度,但同时这也是影响写请求速度的主要原因之一。 可见,Compaction会使得数据读取延迟一直比较平稳,但付出的代价是大量的读延迟毛刺和一定的写阻塞。 Compaction流程 了解了一定的背景知识后,接下来需要从全局角度对Compaction进行了解。整个Compaction始于特定的触发条件,比如flush操作、周期性地Compaction检查操作等。一旦触发,HBase会将该Compaction交由一个独立的线程处理,该线程首先会从对应store中选择合适的hfile文件进行合并,这一步是整个Compaction的核心,选取文件需要遵循很多条件,比如文件数不能太多、不能太少、文件大小不能太大等等,最理想的情况是,选取那些承载IO负载重、文件小的文件集,实际实现中,HBase提供了多个文件选取算法: RatioBasedCompactionPolicy、ExploringCompactionPolicy和 StripeCompactionPolicy 等,用户也可以通过特定接口实现自己的Compaction算法;选出待合并的文件后,HBase会根据这些hfile文件总大小挑选对应的线程池处理, 最后对这些文件执行具体的合并操作。可以通过下图简单地梳理上述流程: 33 触发时机 HBase中可以触发compaction的因素有很多,最常见的因素有这么三种: Memstore Flush、后台线程周期性检查、手动触发。 Memstore Flush: 应该说compaction操作的源头就来自flush操作,memstore flush会产生HFile文件,文件越来越多就需要compact。因此在每次执行完Flush操作之后,都会对当前Store中的文件数进行判断,一旦文件数# > ,就会触发compaction。需要说明的是,compaction都是以Store为单位进行的,而在Flush触发条件下,整个Region的所有Store都会执行compact,所以会在短时间内执行多次compaction。 后台线程周期性检查: 后台线程CompactionChecker定期触发检查是否需要执行compaction,检查周期为: hbase.server.thread.wakefrequency_hbase.server.compactchecker.interval.multiplier。和flush不同的是,该线程优先检查文件数#是否大于,一旦大于就会触发compaction。如果不满足,它会接着检查是否满足major compaction条件,简单来说,如果当前store中hfile的最早更新时间早于某个值mcTime,就会触发major compaction,HBase预想通过这种机制定期删除过期数据。上文mcTime是一个浮动值,浮动区间默认为[7-7_0.2,7+7*0.2],其中7为hbase.hregion.majorcompaction,0.2为hbase.hregion.majorcompaction.jitter,可见默认在7天左右就会执行一次major compaction。用户如果想禁用major compaction,只需要将参数hbase.hregion.majorcompaction设为0 手动触发: 一般来讲,手动触发compaction通常是为了执行major compaction,原因有三,其一是因为很多业务担心自动major compaction影响读写性能,因此会选择低峰期手动触发;其二也有可能是用户在执行完alter操作之后希望立刻生效,执行手动触发major compaction;其三是HBase管理员发现硬盘容量不够的情况下手动触发major compaction删除大量过期数据;无论哪种触发动机,一旦手动触发,HBase会不做很多自动化检查,直接执行合并。 选择合适HFile合并 选择合适的文件进行合并是整个compaction的核心,因为合并文件的大小以及其当前承载的IO数直接决定了compaction的效果。最理想的情况是,这些文件承载了大量IO请求但是大小很小,这样compaction本身不会消耗太多IO,而且合并完成之后对读的性能会有显著提升。然而现实情况可能大部分都不会是这样,在0.96版本和0.98版本,分别提出了两种选择策略,在充分考虑整体情况的基础上选择最佳方案。无论哪种选择策略,都会首先对该Store中所有HFile进行一一排查,排除不满足条件的部分文件: 排除当前正在执行compact的文件及其比这些文件更新的所有文件 (SequenceId更大) 排除某些过大的单个文件,如果文件大小大于hbase.hzstore.compaction.max.size (默认Long最大值) ,则被排除,否则会产生大量IO消耗 经过排除的文件称为候选文件,HBase接下来会再判断是否满足major compaction条件,如果满足,就会选择全部文件进行合并。判断条件有下面三条,只要满足其中一条就会执行major compaction: ...

2017-07-07 · 1 min · 130 words · -

emacs rename file and buffer

emacs rename file and buffer https://stackoverflow.com/questions/384284/how-do-i-rename-an-open-file-in-emacs ;; source: http://steve.yegge.googlepages.com/my-dot-emacs-file (defun rename-file-and-buffer (new-name) “Renames both current buffer and file it’s visiting to NEW-NAME.” (interactive “sNew name: “) (let ((name (buffer-name)) (filename (buffer-file-name))) (if (not filename) (message “Buffer ‘%s’ is not visiting a file!” name) (if (get-buffer new-name) (message “A buffer named ‘%s’ already exists!” new-name) (progn (rename-file filename new-name 1) (rename-buffer new-name) (set-visited-file-name new-name) (set-buffer-modified-p nil))))))

2017-07-05 · 1 min · 65 words · -

sdkman

sdkman #install curl -s http://get.sdkman.io | bash sdk list gradle sdk install gradle sdk install gradle 4.2 sdk default gradle 4.2 http://blog.csdn.net/jjlovefj/article/details/51103578 1.sdkman介绍 sdkman(The Software Development Kit Manager), 中文名为:软件开发工具管理器.这个工具的主要用途是用来解决在类unix操作系统(如mac, Linux等)中多种版本开发工具的切换, 安装和卸载的工作.对于windows系统的用户可以使用Powershell CLI来体验. 例如: 项目A使用Jdk7中某些特性在后续版本中被移除 (尽管这是不好的设计) ,项目B使用Jdk8,我们在切换开发这两个项目的时候,需要不断的切换系统中的JAVA_PATH,这样很不方便,如果存在很多个类似的版本依赖问题,就会给工作带来很多不必要的麻烦. sdkman这个工具就可以很好的解决这类问题,它的工作原理是自己维护多个版本,当用户需要指定版本时,sdkman会查询自己所管理的多版本软件中对应的版本号,并将它所在的路径设置到系统PATH. 2.安装 直接打开终端,执行如下命令: $ curl -s http://get.sdkman.io | bash 上面的命令的含义: 首先sdkman官网下载对应的安装shell script,然后调用bash解析器去执行. 接下来,你需要打开一个新的终端窗口,执行命令: $ source “$HOME/.sdkman/bin/sdkman-init.sh” 再次之后,可以通过输入sdk help确认安装是否完成. jiangjian@jiangjian-ThinkPad-E450c:~$ sdk help Usage: sdk [candidate] [version] ...

2017-07-01 · 2 min · 292 words · -

/dev/net/tun,No such device

‘/dev/net/tun,No such device’ sudo pacman -Syu sudo pacman -S linux sudo modprobe tun modprobe: FATAL: Module tun not found in directory /lib/modules/4.6.3-1-ARCH sudo insmod /lib/modules/4.6.4-1-ARCH/kernel/drivers/net/tun.ko.gz lsmod | grep tun tun 28672 0 https://bbs.archlinux.org/viewtopic.php?id=184992

2017-06-30 · 1 min · 33 words · -

Java TreeMap, 红黑树, Red–black tree, R-B Tree

Java TreeMap, 红黑树, Red–black tree, R-B Tree java.util.TreeMap TreeMap<String,Integer> treeMap = new TreeMap<String,Integer>(); System.out.println("初始化后,TreeMap元素个数为: " + treeMap.size()); //新增元素: treeMap.put("hello",1); treeMap.put("world",2); 红黑树 TreeMap的实现是红黑树算法的实现,所以要了解TreeMap就必须对红黑树有一定的了解,其实这篇博文的名字叫做: 根据红黑树的算法来分析TreeMap的实现,但是为了与Java提高篇系列博文保持一致还是叫做TreeMap比较好。通过这篇博文你可以获得如下知识点: 红黑树的基本概念。 红黑树增加节点、删除节点的实现过程。 红黑树左旋转、右旋转的复杂过程。 Java 中 TreeMap是如何通过put、deleteEntry两个来实现红黑树增加、删除节点的。 我想通过这篇博文你对TreeMap一定有了更深的认识。好了,下面先简单普及红黑树知识。 红黑树简介 红黑树又称红-黑二叉树,它首先是一颗二叉树,它具有二叉树所有的特性。同时红黑树更是一颗自平衡的排序二叉树。 我们知道一颗基本的二叉树他们都需要满足一个基本性质-即树中的任何节点的值大于它的左子节点,且小于它的右子节点。按照这个基本性质使得树的检索效率大大提高。我们知道在生成二叉树的过程是非常容易失衡的,最坏的情况就是一边倒 (只有右/左子树) ,这样势必会导致二叉树的检索效率大大降低 (O(n)) ,所以为了维持二叉树的平衡,大牛们提出了各种实现的算法,如: AVL,SBT,伸展树,TREAP, 红黑树等等。 平衡二叉树必须具备如下特性: 它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。也就是说该二叉树的任何一个子节点,其左右子树的高度都相近。 红黑树顾名思义就是节点是红色或者黑色的平衡二叉树,它通过颜色的约束来维持着二叉树的平衡。对于一棵有效的红黑树二叉树而言我们必须增加如下规则: 节点是红色或者黑色的 根节点是黑色 每个叶子节点 (NIL节点(空节点)) 是黑色的。 如果一个结点是红的,则它两个子节点都是黑的。也就是说在一条路径上不能出现相邻的两个红色结点。 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。 这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这棵树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。所以红黑树它是复杂而高效的,其检索效率O(log n)。下图为一颗典型的红黑二叉树。 对于红黑二叉树而言它主要包括三大基本操作: 左旋、右旋、着色。 左旋 右旋 (图片来自: http://www.cnblogs.com/yangecnu/p/Introduce-Red-Black-Tree.html) 本节参考文献: http://baike.baidu.com/view/133754.htm?fr=aladdin–百度百科 注: 由于本文主要是讲解Java中TreeMap,所以并没有对红黑树进行非常深入的了解和研究,如果诸位想对其进行更加深入的研究Lz提供几篇较好的博文: 红黑树系列集锦 红黑树数据结构剖析 红黑树 二、TreeMap数据结构 ...

2017-06-28 · 7 min · 1371 words · -

ForkJoin

ForkJoin ForkJoinPool 适合执行计算密集型且可进行拆分任务并汇总结果(类似MapReduce)的任务,执行这种任务可以充分利用多核处理器优势提高任务处理速度,实际上 ForkJoinPool 内部的工作窃取队列的高性能 (远高于普通线程池的BlockingQueue) 也决定其适用于执行大量的简短的小任务。 ———————————————— 版权声明:本文为CSDN博主「heng_zou」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/heng_zou/article/details/118193846 什么是 Fork/Join 框架 Fork/Join 框架是 Java7 提供的一个用于并行执行任务的框架(Fork/Join Framework), 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。 我们再通过 Fork 和 Join 这两个单词来理解下 Fork/Join 框架,Fork 就是把一个大任务切分为若干子任务并行的执行,Join 就是合并这些子任务的执行结果,最后得到这个大任务的结果。比如计算 1+ 2+… + 10000,可以分割成 10 个子任务,每个子任务分别对 1000 个数进行求和,最终汇总这 10 个子任务的结果。 ForkJoinPool http://blog.dyngr.com/blog/2016/09/15/java-forkjoinpool-internals/ ForkJoinPool 不是为了替代 ExecutorService, 而是它的补充, 在某些应用场景下性能比 ExecutorService 更好。 (见 Java Tip: When to use ForkJoinPool vs ExecutorService ) https://www.infoworld.com/article/2078440/java-tip-when-to-use-forkjoinpool-vs-executorservice.html ForkJoinPool 主要用于实现"分而治之"的算法, 特别是分治之后递归调用的函数, 例如 quick sort 等。 [[quick-sort]] ForkJoinPool 最适合的是计算密集型的任务, 如果存在 I/O, 线程间同步, sleep() 等会造成线程长时间阻塞的情况时, 最好配合使用 ManagedBlocker ...

2017-06-22 · 4 min · 721 words · -

pstack

pstack http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/pstack.html pstack 跟踪进程栈 此命令可显示每个进程的栈跟踪。pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack 来确定进程挂起的位置。此命令允许使用的唯一选项是要检查的进程的 PID。请参见 proc(1) 手册页。 这个命令在排查进程问题时非常有用,比如我们发现一个服务一直处于work状态 (如假死状态,好似死循环) ,使用这个命令就能轻松定位问题所在;可以在一段时间内,多执行几次pstack,若发现代码栈总是停在同一个位置,那个位置就需要重点关注,很可能就是出问题的地方; 示例: 查看bash程序进程栈: /opt/app/tdev1$ps -fe| grep bash tdev1 7013 7012 0 19:42 pts/1 00:00:00 -bash tdev1 11402 11401 0 20:31 pts/2 00:00:00 -bash tdev1 11474 11402 0 20:32 pts/2 00:00:00 grep bash /opt/app/tdev1$pstack 7013 #0 0x00000039958c5620 in __read_nocancel () from /lib64/libc.so.6 #1 0x000000000047dafe in rl_getc () #2 0x000000000047def6 in rl_read_key () #3 0x000000000046d0f5 in readline_internal_char () ...

2017-06-10 · 1 min · 116 words · -

strace, 跟踪进程中的系统调用

strace, 跟踪进程中的系统调用 sudo pacman -S strace 统计系统调用的耗时 strace -cp <PID> http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/strace.html strace 跟踪进程中的系统调用 strace 常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。 输出参数 每一行都是一条系统调用,等号左边是系统调用的函数名及其参数,右边是该调用的返回值。 strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息,而且不需要以任何特殊的方式来构建内核。 strace cat /dev/null execve("/bin/cat", [“cat”, “/dev/null”], [/* 22 vars */]) = 0 brk(0) = 0xab1000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29379a7000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) … 参数 -c 统计每一系统调用的所执行的时间,次数和出错的次数等. -d 输出strace关于标准错误的调试信息. -f 跟踪由fork调用所产生的子进程. -ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号. -F 尝试跟踪vfork调用.在-f时,vfork不被跟踪. -h 输出简要的帮助信息. -i 输出系统调用的入口指针. ...

2017-06-08 · 1 min · 205 words · -

CPU 使用率, 服务器负载

CPU 使用率, 服务器负载 http://www.jianshu.com/p/e134b8498413 load average: 系统平均负载是 CPU 的L oad, 它所包含的信息不是 CPU 的使用率状况, 而是在一段时间内 CPU 正在处理以及等待 CPU 处理的进程数之和的统计信息, 也就是 CPU 使用队列的长度的统计信息, 这个数字越小越好。 CPU 负载和 CPU 使用率的区别 CPU 使用率: 显示的是程序在运行期间实时占用的 CPU 百分比 CPU 负载: 显示的是一段时间内正在使用和等待使用 CPU 的平均任务数 CPU使用率高, 并不意味着负载就一定大。 举例来说: 如果我有一个程序它需要一直使用CPU的运算功能,那么此时CPU的使用率可能达到100%,但是CPU的工作负载则是趋近于"1",因为CPU仅负责一个工作嘛!如果同时执行这样的程序两个呢?CPU的使用率还是100%,但是工作负载则变成2了。所以也就是说,当CPU的工作负载越大,代表CPU必须要在不同的工作之间进行频繁的工作切换。 举例说明: 网上有篇文章举了一个有趣比喻,拿打电话来说明两者的区别,我按自己的理解阐述一下。 某公用电话亭,有一个人在打电话,四个人在等待,每人限定使用电话一分钟,若有人一分钟之内没有打完电话,只能挂掉电话去排队,等待下一轮。电话在这里就相当于CPU,而正在或等待打电话的人就相当于任务数。 在电话亭使用过程中,肯定会有人打完电话走掉,有人没有打完电话而选择重新排队,更会有新增的人在这儿排队,这个人数的变化就相当于任务数的增减。为了统计平均负载情况,我们5分钟统计一次人数,并在第1、5、15分钟的时候对统计情况取平均值,从而形成第1、5、15分钟的平均负载。 有的人拿起电话就打,一直打完1分钟,而有的人可能前三十秒在找电话号码,或者在犹豫要不要打,后三十秒才真正在打电话。如果把电话看作CPU,人数看作任务,我们就说前一个人(任务)的CPU利用率高,后一个人(任务)的CPU利用率低。 当然, CPU并不会在前三十秒工作,后三十秒歇着,只是说,有的程序涉及到大量的计算,所以CPU利用率就高,而有的程序牵涉到计算的部分很少,CPU利用率自然就低。 结论: 无论CPU的利用率是高是低,跟后面有多少任务在排队没有必然关系。 负载为多少才算比较理想? 这个有争议,各有各的说法,个人比较赞同CPU负载小于等于0.5算是一种理想状态。 不管某个CPU的性能有多好,1秒钟能处理多少任务,我们可以认为它无关紧要,虽然事实并非如此。在评估CPU负载时,我们只以5分钟为单位为统计任务队列长度。如果每隔5分钟统计的时候,发现任务队列长度都是1,那么CPU负载就为1。假如我们只有一个单核的CPU,负载一直为1,意味着没有任务在排队,还不错。 但是我那台服务器,是双核双CPU,等于是有4个内核,每个内核的负载为1的话,总负载为4。这就是说,如果我那台服务器的CPU负载长期保持在4左右,还可以接受。 但是每个内核的负载为1,并不能算是一种理想状态!这意味着我们的CPU一直很忙,不得清闲。网上有说理想的状态是每个内核的负载为0.7左右,我比较赞同,0.7乘以内核数,得出服务器理想的CPU负载,比如我这台服务器,负载在3.0以下就可以。 如何来降低服务器的CPU负载? 最简单办法的是更换性能更好的服务器,不要想着仅仅提高CPU的性能,那没有用,CPU要发挥出它最好的性能还需要其它软硬件的配合。 在服务器其它方面配置合理的情况下,CPU数量和CPU核心数(即内核数)都会影响到CPU负载,因为任务最终是要分配到CPU核心去处理的。两块CPU要比一块CPU好,双核要比单核好。 因此,我们需要记住,除去CPU性能上的差异,CPU负载是基于内核数来计算的!有一个说法,“有多少内核,即有多少负载”。 CPU使用率到多少才算比较理想? CPU使用率长时间60-80%就认为机器有瓶颈出现。 2.load average 多少是正常? 既然load是cpu计算的队列,那就应该和cpu个处理方式和cpu的个数有关系。所以我个人认为应该按系统识别的cpu个数来确定load的临界值,系统识别为8个cpu,那么load为8就是临界点,高于8就属于over load了。 什么叫系统识别CPU个数? 这里涉及到cpu物理个数和超线程技术的问题。对于单处理器在满负载的情况下1.00,则双处理器的负载满额的情况是 2.00,它还有一倍的资源可以利用。从性能的角度上理解,一台主机拥有多核心的处理器与另台拥有同样数目的处理性能基本上可以认为是相差无几。当然实际 情况会复杂得多,不同数量的缓存、处理器的频率等因素都可能造成性能的差异。但即便这些因素造成的实际性能稍有不同,其实系统还是以处理器的核心数量计算负载均值 。这使我们有了两个新的法则: ...

2017-06-08 · 1 min · 92 words · -

Parallel Scavenge

Parallel Scavenge Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量 (Throughput) 。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间) ,虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。 停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户的体验;而高吞吐量则可以最高效率地利用CPU时间,尽快地完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。 Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数及直接设置吞吐量大小的 -XX:GCTimeRatio参数。 MaxGCPauseMillis参数允许的值是一个大于0的毫秒数,收集器将尽力保证内存回收花费的时间不超过设定值。不过大家不要异想天开地认为如果把这个参数的值设置得稍小一点就能使得系统的垃圾收集速度变得更快,GC停顿时间缩短是以牺牲吞吐量和新生代空间来换取的: 系统把新生代调小一些,收集300MB新生代肯定比收集500MB快吧,这也直接导致垃圾收集发生得更频繁一些,原来10秒收集一次、每次停顿100毫秒,现在变成5秒收集一次、每次停顿70毫秒。停顿时间的确在下降,但吞吐量也降下来了。 GCTimeRatio参数的值应当是一个大于0小于100的整数,也就是垃圾收集时间占总时间的比率,相当于是吞吐量的倒数。如果把此参数设置为19,那允许的最大GC时间就占总时间的5% (即1 / (1+19) ) ,默认值为99,就是允许最大1% (即1 / (1+99) ) 的垃圾收集时间。 由于与吞吐量关系密切,Parallel Scavenge收集器也经常被称为"吞吐量优先"收集器。除上述两个参数之外,Parallel Scavenge收集器还有一个参数-XX:+UseAdaptiveSizePolicy值得关注。这是一个开关参数,当这个参数打开之后,就不需要手工指定新生代的大小 (-Xmn) 、Eden与Survivor区的比例 (-XX:SurvivorRatio) 、晋升老年代对象年龄 (-XX:PretenureSizeThreshold) 等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大的吞吐量,这种调节方式称为GC自适应的调节策略 (GC Ergonomics) 。如果读者对于收集器运作原理不太了解,手工优化存在困难的时候,使用Parallel Scavenge收集器配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成将是一个很不错的选择。只需要把基本的内存数据设置好 (如-Xmx设置最大堆) ,然后使用MaxGCPauseMillis参数 (更关注最大停顿时间) 或GCTimeRatio参数 (更关注吞吐量) 给虚拟机设立一个优化目标,那具体细节参数的调节工作就由虚拟机完成了。自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别。 HotSpot VM里多个GC有部分共享的代码。有一个分代式GC框架,Serial/Serial Old/ParNew/CMS都在这个框架内;在该框架内的young collector和old collector可以任意搭配使用,所谓的"mix-and-match"。 而ParallelScavenge与G1则不在这个框架内,而是各自采用了自己特别的框架。这是因为新的GC实现时发现原本的分代式GC框架用起来不顺手。请参考官方文档的Collector Styles一段。 ParallelScavenge (PS) 的young collector就如其名字所示,是并行的拷贝式收集器。本来这个young collector就是"Parallel Scavenge"所指,但因为它不兼容原本的分代式GC框架,为了凸显出它是不同的,所以它的young collector带上了PS前缀,全名变成PS Scavenge。对应的,它的old collector的名字也带上了PS前缀,叫做PS MarkSweep。 这个PS MarkSweep默认的实现实际上是一层皮,它底下真正做mark-sweep-compact工作的代码是跟分代式GC框架里的serial old (这个collector名字叫做MarkSweepCompact) 是共用同一份代码的。也就是说实际上PS MarkSweep与MarkSweepCompact在HotSpot VM里是同一个collector实现,包了两张不同的皮;这个collector是串行的。 ...

2017-06-05 · 1 min · 153 words · -

java, jvm GC

java, jvm GC STW (Stop the World) 悬挂指针 查看当前使用的 GC jmx JMX 查看当前JVM使用的GC MBean java.lang.GarbageCollector java code 输出结果跟JMX查看的结果相同. import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.util.List; public class TestGC { public static void main(String args[]) { List<GarbageCollectorMXBean> l = ManagementFactory.getGarbageCollectorMXBeans(); for (GarbageCollectorMXBean b : l) { System.out.println(b.getName()); } } } prod gc: Copy MarkSweepCompact // 输出 Copy, MarkSweepCompact 代表正在使用单线程的垃圾回收器 -XX:+UseSerialGC 名词解释: 在 GC 的世界里对象指的是通过应用程序利用的数据的集合。是 GC 的基本单位。一般由头 (header) 和域 (field) 构成。 ...

2017-06-04 · 5 min · 866 words · -

Garbage-First G1

Garbage-First G1 http://ifeve.com/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3g1%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/ G1 GC是Jdk7的新特性之一、Jdk7+版本都可以自主配置G1作为JVM GC选项;作为JVM GC算法的一次重大升级、DK7u后G1已相对稳定、且未来计划替代CMS、所以有必要深入了解下: 不同于其他的分代回收算法、G1将堆空间划分成了互相独立的区块。每块区域既有可能属于O区、也有可能是Y区,且每类区域空间可以是不连续的 (对比CMS的O区和Y区都必须是连续的) 。这种将O区划分成多块的理念源于: 当并发后台线程寻找可回收的对象时、有些区块包含可回收的对象要比其他区块多很多。虽然在清理这些区块时G1仍然需要暂停应用线程、但可以用相对较少的时间优先回收包含垃圾最多区块。这也是为什么G1命名为Garbage First的原因: 第一时间处理垃圾最多的区块。 平时工作中大多数系统都使用CMS、即使静默升级到JDK7默认仍然采用CMS、那么G1相对于CMS的区别在: G1在压缩空间方面有优势 G1通过将内存空间分成区域 (Region) 的方式避免内存碎片问题 Eden, Survivor, Old区不再固定、在内存使用效率上来说更灵活 G1可以通过设置预期停顿时间 (Pause Time) 来控制垃圾收集时间避免应用雪崩现象 G1在回收内存后会马上同时做合并空闲内存的工作、而CMS默认是在STW (stop the world) 的时候做 G1会在Young GC中使用、而CMS只能在O区使用 就目前而言、CMS还是默认首选的GC策略、可能在以下场景下G1更适合: 服务端多核CPU、JVM内存占用较大的应用 (至少大于4G) 应用在运行过程中会产生大量内存碎片、需要经常压缩空间 想要更可控、可预期的GC停顿周期;防止高并发下应用雪崩现象

2017-06-04 · 1 min · 37 words · -

程序,进程, 线程, 内核线程, 轻量级进程, 用户线程

程序,进程, 线程, 内核线程, 轻量级进程, 用户线程 程序 程序用于描述进程要完成的功能,是控制进程执行的指令集; 数据集合是程序在执行时所需要的数据和工作区; 程序控制块(Program Control Block,简称PCB),包含进程的描述信息和控制信息,是进程存在的唯一标志。 进程 动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的; 并发性:任何进程都可以同其他进程一起并发执行; 独立性:进程是系统进行资源分配和调度的一个独立单位; 结构性:进程由程序、数据和进程控制块三部分组成。 Linux进程类别 虽然我们在区分Linux进程类别, 但是我还是想说Linux下只有一种类型的进程,那就是task_struct,当然我也想说linux其实也没有线程的概念, 只是将那些与其他进程共享资源的进程称之为线程。 一个进程由于其运行空间的不同, 从而有内核线程和用户进程的区分, 内核线程运行在内核空间, 之所以称之为线程是因为它没有虚拟地址空间, 只能访问内核的代码和数据, 而用户进程则运行在用户空间, 但是可以通过中断, 系统调用等方式从用户态陷入内核态。 用户进程运行在用户空间上, 而一些通过共享资源实现的一组进程我们称之为线程组, Linux下内核其实本质上没有线程的概念, Linux下线程其实上是与其他进程共享某些资源的进程而已。但是我们习惯上还是称他们为线程或者轻量级进程 因此, Linux上进程分3种,内核线程 (或者叫核心进程)、用户进程、用户线程, 当然如果更严谨的,你也可以认为用户进程和用户线程都是用户进程。 关于轻量级进程这个概念, 其实并不等价于线程 不同的操作系统中依据其实现的不同, 轻量级进程其实是一个不一样的概念 内核进程 内核中没有进程的概念 不存在的概念, 内核空间的进程共享内核空间的内存, 没有独立的地址空间, 不能算是进程, 所以没有内核进程这个概念. https://www.coder.work/article/6802420 内核中没有进程的概念,所以你的问题没有意义。 Linux 内核可以并且确实创建了完全在内核上下文中运行的线程,但是所有这些线程都运行在相同的地址空间中。尽管相关线程通常具有相关名称,但没有按 PID 对类似线程进行分组。 如果多个内核线程正在处理同一任务或以其他方式共享数据,则它们需要通过锁定或其他并发算法来协调对该数据的访问。当然,内核中不提供 pthreads API,但是可以使用内核互斥锁、等待队列等来获得与 pthread 互斥锁、条件变量等相同的功能。 将这些执行上下文称为“内核线程”是一个相当不错的名字,因为它们非常类似于用户空间进程中的多个线程。它们都共享(内核的)地址空间,但有自己的执行上下文(堆栈、程序计数器等),并且每个都被独立调度并并行运行。另一方面,内核实际上实现了所有漂亮的 POSIX API 抽象(在用户空间中的 C 库的帮助下),因此在该实现的内部我们没有完整的抽象。 内核线程 内核线程一般特指由内核自己启动的只运行在内核态的一些服务进程. 只运行在内核态 ps命令输出里名字带中括号 内核线程也可以叫内核任务,它们周期性地执行例如,磁盘高速缓存的刷新,网络连接的维护,页面的换入换出等等。 内核线程执行的是内核中的函数,而普通进程只有通过系统调用才能执行内核中的函数。 内核线程只运行在内核态,而普通进程既可以运行在用户态,也可以运行在内核态。 因为内核线程指只运行在内核态,因此,它只能使用大于PAGE_OFFSET (3G)的地址空间。另一方面,不管在用户态还是内核态,普通进程可以使用4GB的地址空间。 内核线程是由kernel_thread( )函数在内核态下创建的 内核线程和用户进程的区分, 内核线程运行在内核空间, 之所以称之为线程是因为它没有虚拟地址空间 内核线程就是内核的分身,一个分身可以处理一件特定事情。这在处理异步事件如异步IO时特别有用。内核线程的使用是廉价的,唯一使用的资源就是内核栈和上下文切换时保存寄存器的空间。支持多线程的内核叫做多线程内核(Multi-Threads kernel )。 ...

2017-06-02 · 13 min · 2746 words · -

System.gc(), System.runFinalization()

System.gc(), System.runFinalization() System.gc: 告诉垃圾收集器打算进行垃圾收集,而垃圾收集器进不进行收集是不确定的。只是建议进行回收。 jvm有自己的gc策略,不建议手动调用。 system.gc其实是做一次full gc system.gc会暂停整个进程 system.gc一般情况下我们要禁掉,使用-XX:+DisableExplicitGC system.gc在cms gc下我们通过-XX:+ExplicitGCInvokesConcurrent来做一次稍微高效点的GC(效果比Full GC要好些) system.gc最常见的场景是RMI/NIO下的堆外内存分配等 System.runFinalization() Runs the finalization methods of any objects pending finalization. Calling this method suggests that the Java Virtual Machine expend effort toward running the finalize methods of objects that have been found to be discarded but whose finalize methods have not yet been run. When control returns from the method call, the Java Virtual Machine has made a best effort to complete all outstanding finalizations. ...

2017-06-02 · 1 min · 98 words · -

JNI左中括号[B[C[[C等

‘JNI左中括号[B[C[[C等’ http://blog.csdn.net/qinjuning/article/details/7599796 在Java存在两种数据类型: 基本类型 和 引用类型 。 在JNI的世界里也存在类似的数据类型,与Java比较起来,其范围更具严格性,如下: 1、primitive types ----基本数据类型,如: int、 float 、char等基本类型 2、reference types----引用类型,如: 类、实例、数组。 特别需要注意: 数组 ------ 不管是对象数组还是基本类型数组,都作为reference types存在。 1、primitive types (基本数据类型)映射参见下表: 这些基本数据类型都是可以在Native层直接使用的 。 2、reference types (引用数据类型)映射参见下表 Java类型 Native Type 描述 注意: 1、引用数据类型则不能直接使用,需要根据JNI函数进行相应的转换后,才能使用 2、多维数组(包括二维数组)都是引用类型,需要使用 jobjectArray 类型存取其值 ; 例如: 二维整型数组就是指向一位数组的数组,其声明使用方式如下: print? //获得一维数组 的类引用,即jintArray类型 jclass intArrayClass = env->FindClass("[I"); //构造一个指向jintArray类一维数组的对象数组,该对象数组初始大小为dimion jobjectArray obejctIntArray = env->NewObjectArray(dimion ,intArrayClass , NULL); ...//具体操作 另外,关于引用类型的一个继承关系如下,我们可以对具有父子关系的类型进行转换: 类描述符 类描述符是类的完整名称 (包名+类名) ,将原来的 . 分隔符换成 / 分隔符。 例如: 在java代码中的java.lang.String类的类描述符就是java/lang/String 其实,在实践中,我发现可以直接用该类型的域描述符取代,也是可以成功的。 例如: jclass intArrCls = env->FindClass("java/lang/String") 等同于 jclass intArrCls = env->FindClass("Ljava/lang/String;") 数组类型的描述符则为,则为: [ + 其类型的域描述符 (后文说明) 例如: int [ ] 其描述符为[I float [ ] 其描述符为[F String [ ] 其描述符为[Ljava/lang/String; 域描述符 1、基本类型的描述符已经被定义好了,如下表所示: 2、引用类型的描述符 一般引用类型则为 L + 该类型类描述符 + ; (注意,这儿的分号";"只得是JNI的一部分,而不是我们汉语中的分段,下同) 例如: String类型的域描述符为 Ljava/lang/String; 对于数组,其为 : [ + 其类型的域描述符 + ; int[ ] 其描述符为[I float[ ] 其描述符为[F String[ ] 其描述符为[Ljava/lang/String; Object[ ]类型的域描述符为[Ljava/lang/Object; 多维数组则是 n个[ +该类型的域描述符 , N代表的是几维数组。例如: int [ ][ ] 其描述符为[[I float[ ][ ] 其描述符为[[F 方法描述符 将参数类型的域描述符按照申明顺序放入一对括号中后跟返回值类型的域描述符,规则如下: (参数的域描述符的叠加)返回 类型描述符。对于,没有返回值的,用V(表示void型)表示。举例如下: Java层方法 JNI函数签名 String test ( ) Ljava/lang/String; int f (int i, Object object) (ILjava/lang/Object;)I void set (byte[ ] bytes) ([B)V 在编程时,如果是利用javah工具的话,这些都不需要我们手动编写对应的类型转换,如果不能用javah工具,就只能手动的 进行类型转换了。

2017-06-02 · 1 min · 169 words · -