redis windows

redis windows 启动redis 服务 redis-server.exe redis-server.exe redis.windows.conf https://github.com/MSOpenTech/redis/releases 修改配置文件 redis.windows.conf ,搜索 maxheap , 然后直接指定好内容即可. maxheap <bytes> maxheap 1024000000

2015-12-01 · 1 min · 18 words · -

redis list

redis list 在 Redis 中, List 类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4294967295。 从元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。然而需要说明的是,如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。 Redis 的列表经常被用作队列(queue),用于在不同程序之间有序地交换消息(message)。 一个程序(称之为生产者,producer)通过LPUSH命令将消息放入队列中,而另一个程序(称之为消费者,consumer)通过RPOP命令取出队列中等待时间最长的消息。 不幸的是,在这个过程中,一个消费者可能在获得一个消息之后崩溃,而未执行完成的消息也因此丢失。 使用RPOPLPUSH命令可以解决这个问题,因为它在返回一个消息之余,还将该消息添加到另一个列表当中,另外的这个列表可以用作消息的备份表: 假如一切正常,当消费者完成该消息的处理之后,可以用LREM命令将该消息从备份表删除。 另一方面,助手(helper)程序可以通过监视备份表,将超过一定处理时限的消息重新放入队列中去(负责处理该消息的消费者可能已经崩溃),这样就不会丢失任何消息了。 头元素和尾元素 头元素指的是列表左端/前端第一个元素,尾元素指的是列表右端/后端第一个元素。 举个例子,列表list包含三个元素: x, y, z,其中x是头元素,而z则是尾元素。 空列表 指不包含任何元素的列表,Redis将不存在的key也视为空列表。 一个列表最多可以包含 232 – 1 个元素 (4294967295, 每个列表超过40亿个元素)。 相关命令 LPUSH LPUSH key value1 [value2] 将一个或多个值插入到列表头部 RPUSH RPUSH key value1 [value2] 将一个或多个值value插入到列表key的表尾。 LPOP key 移出并获取列表的第一个元素 RPOP key RPOP key 移除列表的最后一个元素,返回值为移除的元素。 LLEN key 获取列表长度 LRANGE key start stop LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 BLPOP BLPOP key1 [key2 ] timeout 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 BRPOP key1 [key2 ] timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 ...

2015-12-01 · 4 min · 771 words · -

CAS, Compare and Swap, 比较并交换

CAS, Compare and Swap, 比较并交换 JDK 5 的并发包中提供了很多类,这些类提供了比原有的并发机制更好的性能和伸缩性。要想理解这些类的工作机理,那就不得不提到 CAS。 CAS 全称是 Compare and Swap (比较并交换),是指现代主流 CPU 都支持的一种指令,这个指令能为多线程编程带来更好的性能 (稍后会详细介绍) 。 另外一个可能会被当做 CAS 的是 Compare and Set,是指 JDK 5 并发包中广泛使用的一种基于 Compare and Swap 的并发算法。严格说 CAS 仅指代前者。 java.util.concurrent 包完全建立在CAS之上的,没有CAS就不会有此包。可见CAS的重要性。 java.util.concurrent 包中借助CAS实现了区别于 synchronouse 同步锁的一种乐观锁。 CAS应用 CAS: 全称Compare and swap,字面意思:”比较并交换“,一个 CAS 涉及到以下操作: 我们假设内存中的原数据V,旧的预期值A,需要修改的新值B。 比较 A 与 V 是否相等。 (比较) 如果比较相等,将 B 写入 V。 (交换) 返回操作是否成功。 CAS 有3个操作数,内存值 V, 旧的预期值 A, 要修改的新值 B. 当且仅当预期值 A 和内存值 V 相同时,将内存值 V 修改为 B, 否则什么都不做。 ...

2015-12-01 · 3 min · 454 words · -

ODX(Open Diagnostic Data Exchange)

ODX(Open Diagnostic Data Exchange) http://auto.vogel.com.cn/news_view.html?id=358026 随着汽车电子技术的不断发展,电子控制单元 (ECU) 在现代汽车中得到了广泛的应用。电子控制单元在提高汽车动力性、经济性、舒适性和安全性的同时,也使得车辆中的电子电气系统越来越复杂,这也促使汽车诊断技术有了更大的发展。在整车生命周期中,为了便于交换诊断数据,提高研发、测试、生产及售后的效率,降低诊断数据管理成本,一种开源的标准化诊断数据格式——ODX得到了越来越多的应用。本文介绍了ODX的基本体系结构,其与车辆通信模型接口 (MVCI) 的关系,并分析了现在ODX的主要应用及未来发展方向。 一、 ODX概述 ODX(Open Diagnostic Data Exchange)是一种开放式的诊断数据格式,用于车辆全生命周期中诊断数据的交互。ODX最初由ASAM (自动化及测量系统标准协会)提出并形成标准MCD-2D,在2008年以ODX 2.2.0为基础形成了ISO标准——ISO 22901-1。 在ODX提出之前,由于应用场景、开发工具的不同,诊断开发不同阶段使用的数据格式均不相同。例如,在研发阶段,诊断需求通常采用.doc或.rtf格式描述;在测试验证阶段,以业界常用的Vector CANoe.DiVa工具为例,诊断需求采用.cdd的格式描述;同样,生产、ECU代码实现及售后阶段,诊断需求的描述格式也不相同。然而,诊断开发流程中的各个阶段又相互依存,密不可分。如果诊断需求描述格式不断转换,将难以保证数据的一致性,既增大了需求管理的复杂度,又使各阶段工作衔接困难,增加综合成本。如果在整个诊断开发流程中均使用ODX作为诊断数据格式,由于其开源及标准化属性,上述问题都得以解决。使用ODX作为诊断数据格式的整个数据交互过程如图1所示: 图1 ODX数据交互过程 目前最新版本的ODX为2.2.0,整个ODX数据模型分为七层: ODX-D、ODX-C、ODX-V、ODX-E、ODX-FD、ODX-F、ODX-M,如图2所示: 图2 ODX数据模型 ODX-D部分主要描述了诊断仪与ECU之间的通信过程,包括诊断服务的请求、响应格式及所用到的参数类型等。除此之外,ODX-D部分还使用Single-ECU-job (java)的形式描述了一些特殊的诊断应用,例如安全访问算法的实现。ODX-C部分描述了诊断仪与ECU之间的通信参数,例如网络层定时参数、应用层定时参数、波特率等。ODX-V描述了车辆的信息,例如OEM(原始设备制造商)信息、车型信息、车辆拓扑等。ODX-F部分主要对上传下载的数据进行描述,应用于在线刷新程序。ODX-E部分描述了车辆的配置信息,包括根据特定的车辆环境,地点,使能/关闭可选功能,设定特征曲线等,主要应用于ECU生产、售后阶段。ODX-FD部分描述了面向功能的诊断信息。ODX-M部分描述了多个ECU共同实现的某些诊断功能信息。ODX-D与ODX-C是ODX数据模型的基础,是诊断数据的描述必不可少的两个部分。对于OEM来讲,ODX-V也是不可或缺的。 ODX为开发人员、供应商、售后生产人员之间的诊断数据交互提供了便利,简化了彼此之间的工作流程,降低了OEM对诊断数据维护、管理的成本。除此之外,ODX-D中各诊断层的值继承的应用,使诊断数据得以复用。在多个ECU项目中,通过比较或添加来减少数据量,避免不同ECU的数据拷贝时出错。同时,也可以通过值的本地覆盖来更新数据,有很强的灵活性。ODX中权限属性及强制继承属性的应用保证了诊断数据的安全性和完整性。 二、 ODX与MVCI MVCI(Multiple Vehicle Connect Interface)为车辆通信接口模型,描述了车辆外接设备(例如售后诊断仪、下线设备、测试设备)与ECU之间的通信接口,如图3所示。 图3 车辆通信接口模型 其中应用层实现诊断的上层功能,例如售后诊断仪中读取故障功能、下线设备中钥匙匹配功能、测试设备中的测试用例等。接口实时系统负责与ODX进行交互,将应用层的功能转换成诊断请求,或者将收到的诊断响应解析为应用数据传给应用层。VCI是ECU与车辆外接设备之前的硬件接口,实现不同信号载体之间数据的传递。应用层与实时系统之间的接口称为D-Server API,实时系统与VCI之间的接口称为D-PDU API,这两个接口均由ISO标准化定义,分别为ISO 22900-1、ISO 22900-2。 由图3可知,对于OEM来说,如果使用ODX作为诊断数据格式,无论车辆外接设备应用于售后诊断、下线检测还是测试验证,只需要开发一套通用的接口实时系统,并提供标准的接口,即可根据不同的应用需求开发出不同的工具。节约了工具开发的成本,也避免了各个环节中诊断工具的管理成本。另外,这也将便于以后应用的扩展及通信硬件设备的更新。 接下来以读取发动机转速值为例介绍MVCI处理ODX数据的过程。 图4 MVCI处理ODX数据 应用层将读取发动机转速值的应用命令通过D-Server API传递给接口实时系统; 接口实时系统将读取数据这一应用命令通过ODX映射到诊断服务中(例如通过标识符读数据($22)); 接口实时系统将发动机转速这一命令通过ODX映射到诊断服务的参数中(例如 $0101); 接口实时系统将应用指令组成完整的诊断请求 $22 $01 $01; 接口实时系统通过D-PDU API接口将请求传递给VCI,VCI将这一诊断请求转换成通信信号(例如CAN信号)发给ECU; VCI将接收到的通信信号通过D-PDU API传递给接口实时系统,例如$62 $01 $01 $5D $C0; 接口实时系统将响应中数据通过ODX进行解析,例如发动机转速为$5D $C0; 接口实时系统通过ODX中的参数数据类型将响应中的总线值转换成物理值,例如 ($5DC0*0.125=3000) 接口实时系统通过ODX创建响应对象,包括参数物理值、单位等,例如3000 rpm; ...

2015-11-25 · 1 min · 109 words · -

阻塞,非阻塞,同步,异步

阻塞,非阻塞,同步,异步 作者: 萧萧 链接: https://www.zhihu.com/question/19732473/answer/241673170 来源: 知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 IO 概念区分四个相关概念: 同步 (Synchronous) 异步( Asynchronous) 阻塞( Blocking ) 非阻塞( Nonblocking) 这四个概念的含义以及相互之间的区别与联系,并不如很多网络博客所写的那么简单, 通过举一些什么商店购物, 买书买报的例子就能讲清楚。 进程间通信的同步/异步, 阻塞/非阻塞首先强调一点, 网络上很多博文关于同步/异步, 阻塞非阻塞区别的解释其实都经不起推敲。 例如在 严肃 的这一高赞回答中 , 有如下解释 (不准确) : 同步/异步关注的是消息通信机制 (synchronous communication/ asynchronous communication) 。 所谓同步,就是在发出一个调用时,在没有得到结果之前, 该调用就不返回。异步则是相反,调用在发出之后,这个调用就直接返回了, 所以没有返回结果阻塞/非阻塞关注的是程序在等待调用结果 (消息,返回值) 时的状态.阻塞调用是指调用结果返回之前,当前线程会被挂起。 调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。粗一看, 好像同步/ 非同步, 阻塞/非阻塞 是两种维度的概念, 可以分别对待, 但是稍微推敲一下就会发现上述的解释存在不妥之处。如果“同步”是发起了一个调用后, 没有得到结果之前不返回, 那它毫无疑问就是被“阻塞”了 (即调用进程处于 “waiting” 状态) 。如果“异步”调用发出了以后就直接返回了, 毫无疑问, 这个进程没有被“阻塞”。 所以, 上述的解释是不准确的。 让我们看一下《操作系统概念 (第九版) 》中有关进程间通信的部分是如何解释的: 翻译一下就是: 进程间的通信是通过 send() 和 receive() 两种基本操作完成的。具体如何实现这两种基础操作,存在着不同的设计。 消息的传递有可能是阻塞的或非阻塞的 – 也被称为同步或异步的: 阻塞式发送 (blocking send) . 发送方进程会被一直阻塞, 直到消息被接受方进程收到。非阻塞式发送 (nonblocking send) 。 发送方进程调用 send() 后, 立即就可以其他操作。阻塞式接收 (blocking receive) 接收方调用 receive() 后一直阻塞, 直到消息到达可用。非阻塞式接受 (nonblocking receive) 接收方调用 receive() 函数后, 要么得到一个有效的结果, 要么得到一个空值, 即不会被阻塞。上述不同类型的发送方式和不同类型的接收方式,可以自由组合。也就是说, 从进程级通信的维度讨论时, 阻塞和同步 (非阻塞和异步) 就是一对同义词, 且需要针对发送方和接收方作区分对待。———- 下面对理解同步异步,阻塞非阻塞所需的知识点进行详细叙述———————先修知识用户空间和内核空间进程切换 系统调用 (system call) 中断 (interrupt) 进程的阻塞用户空间和内核空间操作系统为了支持多个应用同时运行,需要保证不同进程之间相对独立 (一个进程的崩溃不会影响其他的进程 , 恶意进程不能直接读取和修改其他进程运行时的代码和数据) 。 因此操作系统内核需要拥有高于普通进程的权限, 以此来调度和管理用户的应用程序。于是内存空间被划分为两部分,一部分为内核空间,一部分为用户空间,内核空间存储的代码和数据具有更高级别的权限。内存访问的相关硬件在程序执行期间会进行访问控制 ( Access Control) ,使得用户空间的程序不能直接读写内核空间的内存。有《微机原理》 课程基础同学可以 Google 搜索 DPL, CPL 这两个关键字了解硬件层面的内存访问权限控制细节进程切换上图展示了进程切换中几个最重要的步骤: 当一个程序正在执行的过程中, 中断 (interrupt) 或 系统调用 (system call) 发生可以使得 CPU 的控制权会从当前进程转移到操作系统内核。操作系统内核负责保存进程 i 在 CPU 中的上下文 (程序计数器, 寄存器) 到 PCBi (操作系统分配给进程的一个内存块) 中。从 PCBj 取出进程 j 的CPU 上下文, 将 CPU 控制权转移给进程 j , 开始执行进程 j 的指令。几个底层概念的通俗 (不严谨) 解释: 中断 (interrupt) CPU 微处理器有一个中断信号位, 在每个CPU时钟周期的末尾, CPU会去检测那个中断信号位是否有中断信号到达, 如果有, 则会根据中断优先级决定是否要暂停当前执行的指令, 转而去执行处理中断的指令。 (其实就是 CPU 层级的 while 轮询) 时钟中断( Clock Interrupt )一个硬件时钟会每隔一段 (很短) 的时间就产生一个中断信号发送给 CPU,CPU 在响应这个中断时, 就会去执行操作系统内核的指令, 继而将 CPU 的控制权转移给了操作系统内核, 可以由操作系统内核决定下一个要被执行的指令。系统调用 (system call) system call 是操作系统提供给应用程序的接口。 用户通过调用 systemcall 来完成那些需要操作系统内核进行的操作, 例如硬盘, 网络接口设备的读写等。从上述描述中, 可以看出来, 操作系统在进行进切换时,需要进行一系列的内存读写操作, 这带来了一定的开销: 对于一个运行着 UNIX 系统的现代 PC 来说, 进程切换通常至少需要花费 300 us 的时间进程阻塞上图展示了一个进程的不同状态: New. 进程正在被创建.Running. 进程的指令正在被执行Waiting. 进程正在等待一些事件的发生 (例如 I/O 的完成或者收到某个信号) Ready. 进程在等待被操作系统调度Terminated. 进程执行完毕 (可能是被强行终止的) 我们所说的 “阻塞”是指进程在发起了一个系统调用 (System Call) 后, 由于该系统调用的操作不能立即完成,需要等待一段时间,于是内核将进程挂起为等待 (waiting) 状态, 以确保它不会被调度执行, 占用 CPU 资源。友情提示: 在任意时刻, 一个 CPU 核心上 (processor) 只可能运行一个进程 。I/O System Call 的阻塞/非阻塞, 同步/异步这里再重新审视 阻塞/非阻塞 IO 这个概念, 其实阻塞和非阻塞描述的是进程的一个操作是否会使得进程转变为“等待”的状态, 但是为什么我们总是把它和 IO 连在一起讨论呢?原因是, 阻塞这个词是与系统调用 System Call 紧紧联系在一起的, 因为要让一个进程进入 等待 (waiting) 的状态, 要么是它主动调用 wait() 或 sleep() 等挂起自己的操作, 另一种就是它调用 System Call, 而 System Call 因为涉及到了 I/O 操作, 不能立即完成, 于是内核就会先将该进程置为等待状态, 调度其他进程的运行, 等到 它所请求的 I/O 操作完成了以后, 再将其状态更改回 ready 。操作系统内核在执行 System Call 时, CPU 需要与 IO 设备完成一系列物理通信上的交互, 其实再一次会涉及到阻塞和非阻塞的问题, 例如, 操作系统发起了一个读硬盘的请求后, 其实是向硬盘设备通过总线发出了一个请求,它即可以阻塞式地等待IO 设备的返回结果,也可以非阻塞式的继续其他的操作。 在现代计算机中,这些物理通信操作基本都是异步完成的, 即发出请求后, 等待 I/O 设备的中断信号后, 再来读取相应的设备缓冲区。 但是,大部分操作系统默认为用户级应用程序提供的都是阻塞式的系统调用 (blocking systemcall) 接口, 因为阻塞式的调用,使得应用级代码的编写更容易 (代码的执行顺序和编写顺序是一致的) 。但同样, 现在的大部分操作系统也会提供非阻塞I/O 系统调用接口 (Nonblocking I/O system call) 。 一个非阻塞调用不会挂起调用程序, 而是会立即返回一个值, 表示有多少bytes 的数据被成功读取 (或写入) 。非阻塞I/O 系统调用( nonblocking system call )的另一个替代品是 异步I/O系统调用 (asychronous system call) 。 与非阻塞 I/O 系统调用类似,asychronous system call 也是会立即返回, 不会等待 I/O 操作的完成, 应用程序可以继续执行其他的操作, 等到 I/O 操作完成了以后,操作系统会通知调用进程 (设置一个用户空间特殊的变量值 或者 触发一个 signal 或者 产生一个软中断 或者 调用应用程序的回调函数) 。此处, 非阻塞I/O 系统调用( nonblocking system call ) 和 异步I/O系统调用 (asychronous system call) 的区别是: 一个非阻塞I/O 系统调用 read() 操作立即返回的是任何可以立即拿到的数据, 可以是完整的结果, 也可以是不完整的结果, 还可以是一个空值。而异步I/O系统调用 read () 结果必须是完整的, 但是这个操作完成的通知可以延迟到将来的一个时间点。下图展示了同步I/O 与 异步 I/O 的区别 (非阻塞 IO 在下图中没有绘出) . 注意, 上面提到的 非阻塞I/O 系统调用( nonblocking system call ) 和 异步I/O系统调用 都是非阻塞式的行为 (non-blocking behavior) 。 他们的差异仅仅是返回结果的方式和内容不同。非阻塞 I/O 如何帮助服务器提高吞吐量考虑一个单进程服务器程序, 收到一个 Socket 连接请求后, 读取请求中的文件名,然后读请求的文件名内容,将文件内容返回给客户端。 那么一个请求的处理流程会如下图所示。R 表示读操作W 表示写操作C 表示关闭操作在这个过程中, 我们可以看到, CPU 和 硬盘IO 的资源大部分时间都是闲置的。 此时, 我们会希望在等待 I/O 的过程中继续处理新的请求。方案一: 多进程每到达一个请求, 我们为这个请求新创建一个进程来处理。 这样, 一个进程在等待 IO 时, 其他的进程可以被调度执行, 更加充分地利用 CPU 等资源。问题: 每新创建一个进程都会消耗一定的内存空间, 且进程切换也会有时间消耗, 高并发时, 大量进程来回切换的时间开销会变得明显起来。方案二: 多线程和多进程方案类似,为每一个请求新建一个线程进行处理,这样做的重要区别是, 所有的线程都共享同一个进程空间问题: 需要考虑是否需要为特定的逻辑使用锁。引申问题: 一个进程中的某一个线程发起了 system call 后, 是否造成整个进程的阻塞? 如果会, 那么多线程方案与单进程方案相比就没有明显的改善。解决办法1: 内核支持的线程 (kenerl supported threads) 操作系统内核能够感知到线程, 每一个线程都会有一个内核调用栈 (kenerl stack) 和 保存CPU 寄存器下文的 table 。在这种方案中, 如果 CPU 是多核的, 不同的线程还可以运行在不同的 CPU processor 上。 既实现了IO 并发, 也实现了 CPU 并发。问题: 内核支持线程可移植性差, 其实现对于不同的操作系统而言有所差别。解决办法2: 用户支持的线程 (user supported threads) 内核感知不到用户线程, 每一个用户的进程拥有一个调度器, 该调度器可以感知到线程发起的系统调用, 当一个线程产生系统调用时, 不阻塞整个进程, 切换到其他线程继续运行。 当 I/O 调用完成以后, 能够重新唤醒被阻塞的线程。实现细节: 应用程序基于线程库 thread libray 编写线程库中包含 “虚假的” read(), write(), accept()等系统调用。线程库中的 read(), write(), accept() 的底层实现为非阻塞系统调用 (Non-blocking system call) , 调用后,由于可以立即返回, 则将特定的线程状态标记为 waiting, 调度其他的可执行线程。 内核完成了 IO 操作后, 调用线程库的回调函数, 将原来处于 waiting 状态的线程标记为 runnable.从上面的过程可以看出,用户级支持线程 (User-Supported Threads) 的解决方案基于非阻塞IO系统调用( non-blocking system call) , 且是一种基于操作系统内核事件通知 (event-driven) 的解决方案, 该方案可以降低系统处理并发请求时的进程切换开销。 基于这个方案, 可以引申到更为宽泛的 event-driven progreamming 话题上。 但是这里就不作赘述了。总结: 阻塞/非阻塞, 同步/异步的概念要注意讨论的上下文: 在进程通信层面, 阻塞/非阻塞, 同步/异步基本是同义词, 但是需要注意区分讨论的对象是发送方还是接收方。发送方阻塞/非阻塞 (同步/异步) 和接收方的阻塞/非阻塞 (同步/异步) 是互不影响的。在 IO 系统调用层面 ( IO system call ) 层面, 非阻塞 IO 系统调用 和 异步 IO 系统调用存在着一定的差别, 它们都不会阻塞进程, 但是返回结果的方式和内容有所差别, 但是都属于非阻塞系统调用 ( non-blocing system call ) 2. 非阻塞系统调用 (non-blocking I/O system call 与 asynchronous I/O system call) 的存在可以用来实现线程级别的 I/O 并发, 与通过多进程实现的 I/O 并发相比可以减少内存消耗以及进程切换的开销。编辑于 03-02 ...

2015-11-13 · 3 min · 584 words · -

jstack

jstack jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下: jstack [option] PID jstack [option] executable core jstack [option] [server-id@]remote-hostname-or-ip 可以显示所有的线程 H 打印线程信息,p指定pid,这两个参数的作用是显示进行pid下的所有线程的资源占用情况。 top -Hp PID 找到cpu占用最高的线程 10进制转16进制 printf "%x\n" PID #-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况 #http://www.wiloon.com/?p=10225 #-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息 (比如Native方法) #-m prints mixed mode (both Java and native C/C++ frames) stack trace. #-F Force a stack dump when 'jstack [-l] pid' does not respond. jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。 第一步先找出Java进程ID,我部署在服务器上的Java应用名称为mrf-center: ps -ef | grep mrf-center | grep -v grep ...

2015-11-11 · 4 min · 715 words · -

SVN中Branch/tag

SVN中Branch/tag http://blog.csdn.net/adupt/article/details/4203133 SVN中Branch/tag的比较 分类: SVN2009-05-20 10:23 8700人阅读 评论(0) 收藏 举报 svnbranchmergetortoisesvnurl测试 在SVN中Branch/tag在一个功能选项中,在使用中也往往产生混淆。 在实现上,branch和tag,对于svn都是使用copy实现的,所以他们在默认的权限上和一般的目录没有区别。至于何时用tag,何时用branch,完全由人主观的根据规范和需要来选择,而不是强制的 (比如cvs) 。 一般情况下, tag,是用来做一个milestone的,不管是不是release,都是一个可用的版本。这里,应该是只读的。更多的是一个显示用的,给人一个可读 (readable) 的标记。 branch,是用来做并行开发的,这里的并行是指和trunk进行比较。 比如,3.0开发完成,这个时候要做一个tag,tag_release_3_0,然后基于这个tag做release,比如安装程序等。trunk进入 3.1的开发,但是3.0发现了bug,那么就需要基于tag_release_3_0做一个branch,branch_bugfix_3_0,基于这 个branch进行bugfix,等到bugfix结束,做一个tag,tag_release_3_0_1,然后,根据需要决定 branch_bugfix_3_0是否并入trunk。 对于svn还要注意的一点,就是它是全局版本号,其实这个就是一个tag的标记,所以我们经常可以看到,什么什么release,基于xxx项目的 2xxxx版本。就是这个意思了。但是,它还明确的给出一个tag的概念,就是因为这个更加的可读,毕竟记住tag_release_1_0要比记住一个 很大的版本号容易的多。 svn中建立branch或者tag的方法比较简单,totoiseSVN中的操作是: 1.选择Branch/tag.. 2.在出来的界面中的To URL中填上URL,一般是svn://IP/Project/branches/branch-1, 这样就建立了一个branch-1的branch. 建立tag是一样的操作,只不过URL一般是svn://IP/Project/tags/tag-1 3.后面的Create copy from是用于选择从你当前的working base中的哪个版本中建立branch/tag,可以根据自己的选择来订制,一般选择Head Revision subclipse中几乎是一样的操作。 Merge分为很多种: 1.多个branch之间merge 2.branch merge到trunk 3.trunk merge到branch 第2种用的比较多,比如在otfs接口中netamount的需求提出后就得建立一个netamount的branch,trunk继续在非 netamount的情况下继续开发,netamount单独开发,当netamount功能测试通过后,将netamount branch merge到trunk下,然后将trunk release。 第3种情况用的也不少,如上的例子,当用户进行netamount测试时,如果用户不想只测试netamount的功能,则需要将trunk中的修改merge到netamount branch,然后从netamount branch中发布一个版本供用户测试。 branch merge to trunk在tortoiseSVN操作如下: 1.选择TortoiseSVN->Merge 2.选择Reintegrate a branch 3.选择From URL,URL填好之后可以点击Show Log,可以看看这个branch是否是你要merge的内容,下面的Working copy中也可以Show Log,可以确认一下你的工作目录是否是trunk。确认后点击Next 4.Merge Options里面有些选项,根据需要来选择,Test Merge按钮会告诉你这次Merge会做哪些操作,最好先Test Merge一下!如果是预期的Merge操作,点击Merge则可以将branch Merge到本地工作目录下 ...

2015-11-11 · 1 min · 131 words · -

jvisualvm, JVM 监控分析工具(VisualVM)

jvisualvm, JVM 监控分析工具(VisualVM) Visual GC GC time Time taken to perform garbage collection Compile time Time spent in just-in-time (JIT) compilation if visualvm can not find java start visualvm with -jdkhome visualvm.exe -jdkhome D:\java\jdk7 插件安装目录 C:\Users\user0\AppData\Roaming\VisualVM\8u131 在Java多线程程序运行时,多数情况下我们不知道到底发生了什么,只有出了错误的日志的时候,我们才知道原来代码中有死锁。撇开代码检查工具,我们先讨论一下利用VisualVM监控,分析我们的多线程的运行情况。 (注: 实践本文内容的JDK的版本需要1.6.07以上) 什么是VisualVM VisualVM是JDK的一个集成的分析工具,自从JDK 6 Update 7以后已经作为Sun的JDK的一部分。 VisualVM可以做的: 监控应用程序的性能和内存占用情况、监控应用程序的线程、进行线程转储(Thread Dump)或堆转储(Heap Dump)、跟踪内存泄漏、监控垃圾回收器、执行内存和CPU分析,保存快照以便脱机分析应用程序;同时它还支持在MBeans上进行浏览和操作。尽管 VisualVM自身要在JDK6以上的运行,但是JDK1.4以上版本的程序它都能被它监控。 在JDK1.6.07以上的版本中: 到$JAVA_HOME/bin,点击jvisualvm.exe图标就可以启动VisualVM;当然也可以点击这里获取官方的最新版本,支持: 英文,中文,日文。 VisualVM功能集成较多,我们这里只讨论它对象线程的监控分析。 VisualVM监控线程 当我们运行VisualVM的时候,可以在应用程序》本地中看到VisualVM和eclipse的运行程序,然后我们启动eclipse中的一个 线程: com.longtask.thread.TestVisualVm,可以看到在菜单中多了一个该线程的显示。点击右边的 线程 菜单,可以看到线程运行的跟踪情况。 点击 thread dump,可以生成该线程的运行情况的tdump文件,通过thread dump提供的相关信息,我们可以看到线程在什么地方被阻塞了以及线程的其他状态。 把日志另存为文件,到Thread Dump Analyzer的主页点击图标下载TDA,然后用TDA打开刚才VisualVM保存的 thread dump文件,查看相关的分析结果。 远程监控 我们也可以用VisualVM来监控远程java线程的运行情况。 ...

2015-11-04 · 1 min · 208 words · -

pacstrap,command not found

‘pacstrap,command not found’ http://archlinuxarm.org/forum/viewtopic.php?f=60&t=8529 pacman -S pkgfile pkgfile --update pkgfile pacstrap pacman -S extra/arch-install-scripts command-not-found.com 提供 command not found 的搜索 command-not-found.com

2015-11-01 · 1 min · 21 words · -

linux 文本 统计

linux 文本, 字符 统计 # 统计一个目录下所有 .md 文件的字符数 find content/post -name '*.md' -exec wc -w '{}' \; > /tmp/foo.txt awk '{sum+=$1} END {print sum}' /tmp/foo.txt # 另外一种统计, 数字好像不太对, 有时间再研究一下. ls -lR content/post |grep '\.md'|wc -w 用 grep -c 来统计匹配的行数 grep -c 的作用类似grep | wc -l,不同的是,如果是查找多个文件,grep -c会统计每个文件匹配的行数,每行一个文件的列出来,而 wc -l 则列出总的统计数字。 另外grep -c 要比 grep | wc -l快一点。 grep -c night restart.07014 返回2 没有 返回0 http://blog.csdn.net/xuejiayue1105/article/details/1483940

2015-10-28 · 1 min · 64 words · -

java.lang.OutOfMemoryError,unable to create new native thread

‘java.lang.OutOfMemoryError,unable to create new native thread’ http://www.blogjava.net/ldd600/archive/2009/09/25/296397.html 星期一早上到了公司,据称产品环境抛出了最可爱的异常—OutOfMemory, 它是这样来描述他自己的: java.lang.OutOfMemoryError: unable to create new native thread 而且这位仁兄竟然还堂而皇之地同时出现在了3个application里面,所有应用全部遭殃。 那可爱的OOM是如何产生的呢?直接原因是创建的线程太多了,根本原因是某个地方的内存限制了。 搜罗了一下在网上找到了一个计算公式: (MaxProcessMemory - JVMMemory – ReservedOsMemory) / (ThreadStackSize) = Number of threads MaxProcessMemory: 进程最大的寻址空间,但我想这个值应该也不会超过虚拟内存和物理内存的总和吧。关于不同系统的进程可寻址的最大空间,可参考下面表格: Maximum Address Space Per Process Operating System Maximum Address Space Per Process Redhat Linux 32 bit 2 GB Redhat Linux 64 bit 3 GB Windows 98/2000/NT/Me/XP 2 GB Solaris x86 (32 bit) 4 GB Solaris 32 bit 4 GB ...

2015-10-27 · 2 min · 405 words · -

tcpdump

tcpdump 用简单的话来定义 tcpdump, 就是: dump the traffic on a network, 根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump 可以将网络中传送的数据包的"头"完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供 and、or、not 等逻辑语句来帮助你去掉无用的信息。 tcpdump 工作在数据链路层 install #archlinux pacman -S tcpdump #redhat yum install -y tcpdump commands # tcpdump 默认读取第一个网络接口上所有流过的数据包。 tcpcump 过滤 tcp flag TCP 协议头中flags 域的可用取值: tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg # 只捕获TCP SYN包: tcpdump -i <interface> "tcp[tcpflags] & (tcp-syn) != 0" # 只捕获TCP ACK包: tcpdump -i <interface> "tcp[tcpflags] & (tcp-ack) != 0" # 只捕获TCP FIN包: tcpdump -i <interface> "tcp[tcpflags] & (tcp-fin) != 0" # 之捕获TCP SYN或ACK包: tcpdump -r <interface> "tcp[tcpflags] & (tcp-syn|tcp-ack) != 0" tcpdump -nn -i eth0 dst host 172.16.0.213 and 'tcp[tcpflags] & (tcp-rst) != 0' # 打印 TCP 会话中的的开始和结束数据包, 并且数据包的源或目的不是本地网络上的主机 .(nt: localnet, 实际使用时要真正替换成本地网络的名字)) tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net localnet' https://blog.csdn.net/cbbbc/article/details/48897363 ...

2015-10-26 · 25 min · 5319 words · -

jmeter beanshell 数字转字符串补零

jmeter beanshell 数字转字符串补零 http://localhost:7000/?id=${__counter(FALSE,eIndex)}&p=prefix${__BeanShell(333+${eIndex})}sufix http://localhost:7000/?id=${__BeanShell(String.format("%03d"\,new Object[]{1}))} #逗号用反斜杠转换 #参数传Object数组 https://help.flood.io/docs/how-to-pad-strings-in-jmeter

2015-10-23 · 1 min · 9 words · -

parted command

parted command install parted # archlinux pacman -S parted # ubuntu apt install parted # 查看磁盘信息 lsblk # 查看 /dev/sdd 当前的分区情况 # 只能看分区信息, 想知道硬盘上有没有空闲的没创建分区的空间得自己算, 看 start end 是不是连续来判断. sudo parted /dev/sdd print # list disk and partitions # -l, --list sudo parted -l # -a 分区对齐, 对齐类型 # -a, --align sudo parted -a optimal /dev/sdx # 查看磁盘分区 (parted) p # set disk label, 硬盘没有其它分区的时候, 设置分区表类型 (parted) mklabel gpt # or mklabel msdos # 设置 单位为 s, MiB, GiB, MB,GB unit mib # 查看 parted 命令帮助 help mkpart # mkpart part-type fs-type start end # fs-type 是文件系统类型,支持的类型列表可以通过 help mkpart 查看。 # mkpart 并不会实际创建文件系统, fs-type 参数仅是让 parted 设置一个 1-byte 编码,让启动管理器可以提前知道分区中有什么格式的数据。 # 按比例分区, 可以不设置 unit xxx mkpart 磁盘分区名称 起始磁柱值 截止磁柱值 # fs-type: ext4, fat32 mkpart primary ext4 0% 100% mkpart primary ext4 510G 100% # 指定分区名和起止位置,起点会自动设置成2048s mkpart data 0% 100% # 创建efi分区建议550M, linux的efi分区用 fat32, 系统分区不能用fat,fat 会有各种问题,比如不允许使用冒号作文件名 (parted) mkpart primary fat32 1 551 # 设置 efi 分区标记 (parted) set 1 esp on # 设置常规 bios 引导, esp is an alias for boot on GPT (parted) set 1 boot on # grub引导 (parted) set 1 bios_grub on # 给分区取个名字, msdos disk label do not support partition names. name 1 boot # 创建swap分区 16G+ mkpart primary 551 17536 name 2 swap mkpart primary 17536 -1 name 3 rootfs #检查是否分区对齐 align-check optimal 1 # 退出parted (parted) q # 查看磁盘信息 lsblk # mkswap sudo mkswap /dev/sdx2 swapon /dev/sdx2 # 查看磁盘分区UUID, 没有 root 权限时, blkid 没有输出 ```bash sudo blkid #genfstab -p -U /mnt > /mnt/etc/fstab ...

2015-10-22 · 3 min · 454 words · -

test

test Downloading: http://repository.springsource.com/maven/bundles/release/org/json/org.ow2.chameleon.commons.json/20090911-0002/org.ow2.chameleo n.commons.json-20090911-0002.jar

2015-10-20 · 1 min · 4 words · -

MySQL btree索引 hash索引

‘MySQL btree索引 hash索引’ MySQL, b tree索引 hash索引, B树 http://www.cnblogs.com/vicenteforever/articles/1789613.html Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。可 能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢?任何事物都是有两面性的,Hash 索引也一样,虽然 Hash 索引效率高,但是 Hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。 (1) Hash 索引仅仅能满足"=",“IN"和”<=>“查询,不能使用范围查询。 由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。 (2) Hash 索引无法被用来避免数据的排序操作。 由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算; (3) Hash 索引不能利用部分索引键查询。 对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。 (4) Hash 索引在任何时候都不能避免表扫描。 ...

2015-10-15 · 1 min · 94 words · -

Asking The Right Questions, 学会提问

Asking The Right Questions, 学会提问 Asking The Right Questions: A Guide to Critical Thinking Author/作者: [美]尼尔·布朗 (Neil Browne),斯图尔特·基利 (Stuart Keel) 译作名: 学会提问 译者: 许蔚翰, 吴礼敬 时间: 2023.12 - 我们最常见的倾向就是只愿听那些价值观和我们相似的人的话, 我们需要下大力气去抵制这种倾向. 我们必须要与这种倾向做斗争. P52/550 主要价值观 自主决断: 仔细听听那些和我们价值观倾向不同的人的话. 好奇心 一旦你发现说理透彻, 认证严密的人, 不论其肤色, 年龄, 财富, 国籍如何, 都要依赖他的观点, 直到更加透彻, 严谨的认证出现为止. 斯蒂芬 科尔伯特 (Stephen Colbert): “我们并不是什么事实的拥趸, 你看, 事实还会发生改变, 可是我的观点从来都不会变, 不论它面对的是什么样的事实.” 任何下决心死抱自己的结论不放手的人, 都有可能找到许多理由来证明自己的观点. 这种认证方式 被称作"操控型认证"(managed reasoning), 意思就是这种认证方式经过事先挑选, 以便得出某个特定的结论. P56/550 描述性论题 规定性论题 薄弱的理由必然导致薄弱的认证. P114/550 理由的提示词 由于, as a result of 研究显示, studies show 因为这个事实, because of the fact that 因为这个原因, for the reason that 由以下材料支撑, is supported by 因为证据显示, because the evidence is 谬误 人身攻击型谬误 ad hominem fallacy, ad hominem, 针对个人进行人身攻击,而不是直接反驳其提供的理由. P247/550 https://book.douban.com/subject/35513147/

2015-10-13 · 1 min · 105 words · -

迭代回顾, Sprint Retrospective

迭代回顾, Sprint Retrospective Scrum - Sprint Retrospective 在Scrum中,每个Sprint结束的时候会有两个会议 (Sprint Review/Demo和Sprint Retrospective回顾) 。 这两个会议是对过去的一个Sprint的一个总结,其中Review/Demo是检查过去一个Sprint的产出 (What) ,主要是PO根据先前的计划来检查Team在过去一个Sprint的工作成果,包括一些Demo,以及未完成部分的总结和分析;而Retrospective则是回顾过去一个Sprint整个Team的运作模式,有什么好的和不好的实践,怎样在未来的Sprint做的更好,强调How。 Sprint Retrospective (回顾) Sprint Retrospective会议主要是整个Team讨论过去的一个Sprint的运作,如何改进使Team更良好的运作。讨论的内容可以是任何有关Team建设的问题,包括工作流程、团队实践、团队内部/外部沟通、团队气氛以及相关工具的使用等等。 Scrum并不是一种方法,而是给软件开发流程提供了一种框架,在整个框架下,不同的项目、团队需要根据具体条件,适时调整实践方法。而Retrospective会议正是一个Scrum团队自我调整的机会。 会议的参加者包括整个Scrum团队、Scrum Master和Product Owner。会议由Scrum Master主持,一般以下边两个问题开始: 过去的一个Sprint里,我们有哪些好的方面? 过去一个Sprint存在哪些问题? 整个Team就这两个问题进行公开讨论,方式也可以是多样的。可以大家一起讨论,Scrum Master在讨论过程中将大家的观点记录在白板上;也可以让Team每个成员在便签纸上写下自己的答案,可以要求每个问题至少写三点,然后每个人把自己的答案贴在白板上,并给出相关解释。 讨论完毕后,对讨论结果进行分类。对于好的方便,在下个Sprint继续保持并发扬;对于存在的问题,列出Action Point去解决问题。列出的Action Point也会在下个Sprint的backlog中体现出来,并且是高优先级的项目。 探索者 (E) 代表对这个会议的内容充满期待,很有兴趣听听看看大家都是怎么看待过去这段时间的工作的,想以此来分析我们为什么是这样工作的; 推销者 (S) 是带着想法过来的,他有一个idea想借这个会议推销给大家,比如一个新的工作方式的建议,给团队增加一个流程来改进某一个方面的问题,总之这个人看到了问题,也带来的解决办法; 度假者 (V) 把这个会议当做一个休闲的方式,他们觉得有个机会大家一起聊聊天,胡扯一通挺有意思的,可能比自己工作的时候更让他放松。度假者对会议的内容是没有期待的。 囚犯 (P) 是极不愿意来参加这个会议的,他们要么就是厌恶会议,要么就是忙得没时间参加会议,总之他们是被迫来的,他们期望着会议能马上结束就好,没有心思参与到会议的讨论中来。 http://blog.csdn.net/ljinddlj/article/details/5328404 https://www.jianshu.com/p/95a59fe7844c

2015-10-12 · 1 min · 46 words · -

LVM

LVM commands # lvreduce, 用于减小 LVM 逻辑卷(Logical Volume)的大小 # -r, 同时调整(resize)文件系统的大小(调用 resize2fs xfs_growfs 等) # -L -40G 减小逻辑卷的大小 40GB(注意 - 表示减小) # /dev/ubuntu-vg/root 要调整的逻辑卷路径(通常是根分区) sudo lvreduce -r -L -40G /dev/ubuntu-vg/root LVM 的基本概念 通过 LVM 技术,可以屏蔽掉磁盘分区的底层差异,在逻辑上给文件系统提供了一个卷的概念,然后在这些卷上建立相应的文件系统。下面是 LVM 中主要涉及的一些概念。 PM 物理存储设备 (Physical Media): 指系统的存储设备文件,比如 某一块硬盘, /dev/sda、/dev/sdb 等。 或者 设备映射器(Device Mapper)管理的加密分区. /dev/mapper/nvme0n1p8_crypt PV (物理卷 Physical Volume): PV 可以看做是硬盘上的分区, 指硬盘分区或者从逻辑上看起来和硬盘分区类似的设备 (比如 RAID 设备)。 PE (Physical Extent):PV(物理卷)中可以分配的最小存储单元称为 PE,PE 的大小是可以指定的。 VG (卷组, Volume Group): 卷组: 物理卷的组合. 类似于非 LVM 系统中的物理硬盘,一个 LVM 卷组由一个或者多个 PV(物理卷) 组成。 卷组是 LVM 的中间层,VG 将多个物理卷(Physical Volumes, PV)组合在一起, 以便在其上创建逻辑卷(Logical Volumes, LV)。 ...

2015-10-12 · 3 min · 635 words · -

java中byte数组与int类型的转换 (两种方式)

java中byte数组与int类型的转换 (两种方式) http://blog.csdn.net/zhouyong0/article/details/8078619 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法,我们都知道,在socket传输中,发送、者接收的数据都是 byte数组,但是int类型是4个byte组成的,如何把一个整形int转换成byte数组,同时如何把一个长度为4的byte数组转换为int类型。下面有两种方式。 public static byte[] int2byte(int res) { byte[] targets = new byte[4]; targets[0] = (byte) (res & 0xff);// 最低位 targets[1] = (byte) ((res » 8) & 0xff);// 次低位 targets[2] = (byte) ((res » 16) & 0xff);// 次高位 targets[3] = (byte) (res »> 24);// 最高位,无符号右移。 return targets; } public static int byte2int(byte[] res) { // 一个byte数据左移24位变成0x??000000,再右移8位变成0x00??0000 int targets = (res[0] & 0xff) | ((res[1] « 8) & 0xff00) // | 表示安位或 ...

2015-10-12 · 1 min · 156 words · -