分类目录: Java

Java中的垃圾回收

前文前文中对标记删除算法的介绍更多还是偏理论性质的。实践中,为了更好地满足现实的场景及需求,还需要对算法进行大量的调整。举个简单的例子,我们来看下JVM需要记录哪些信息才能让我们得以安全地分配对象空间。

碎片及整理(Fragmenting and Compacting)

JVM在清除不可达对象之后,还得确保它们所在的空间是可以进行复用的。对象删除会导致碎片的出现,这有点类似于磁盘碎片,这会带来两个问题:

  • 写操作会变得更加费时,因为查找下一个可用空闲块已不再是一个简单操作。
  • JVM在创建新对象的,会在连续的区块中分配内存。因此如果碎片已经严重到没有一个空闲块能足够容纳新创建的对象时,内存分配便会报错。

为了避免此类情形,JVM需要确保碎片化在可控范围内。因此,在垃圾回收的过程中,除了进行标记和删除外,还有一个“内存去碎片化”的过程。在这个过程当中,会给可达对象重新分配空间,让它们互相紧挨着对方,这样便可以去除碎片。下图展示的便是这一过程:

fragmented-vs-compacted-heap

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 3票) Loading ... Loading ... | 归档目录:Java | 标签: , , |

Java问题排查工具箱

问题排查除了最重要的解决思路和逻辑推导能力外,工具也是不可缺少的一部分,一个好用的工具可以事半功倍,甚至在某些情况下会因为没有相应的工具而压根就没法继续进行下去,这篇文章就来讲讲在排查Java问题时通常要用到的一些工具(:这种文章值得收藏,看一遍其实很容易忘)。

日志相关工具
查问题的时候会非常依赖日志,因此看日志的相关工具非常重要,通常的话掌握好tail,find,fgrep,awk这几个常用工具的方法就可以,说到这个就必须说关键的异常和信息日志输出是多么的重要(看过太多异常的随意处理,例如很典型的是应用自己的ServletContextListener实现,很多的Listener实现都会变成往外抛RuntimeException,然后直接导致tomcat退出,而tomcat这个时候也不会输出这个异常信息,这种时候要查原因真的是让人很郁闷,尽管也有办法)。
日志的标准化也非常重要,日志的标准化一方面方便像我这种要查各种系统问题的人,不标准的话连日志在哪都找不到;另一方面对于分布式系统而言,如果标准化的话是很容易做日志tracing的,对问题定位会有很大帮助。

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 5票) Loading ... Loading ... | 同时归档在:软件技术 | 标签: , |

jAlbum 0.1.6版本截图

新增主要功能:修改页面适配手机屏幕。

Android 手机截图效果:

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 15票) Loading ... Loading ... | 同时归档在:Jetty, WEB网络, 移动互联, 软件技术 | 标签: , |

开源照片整理系统jAlbum 0.1.3版本发布

第三个版本,jAlbum完整版差不多完工了:https://github.com/shentar/jAlbum/releases/tag/jAlbum_0.1.3

最后解决了文件系统监控的问题。利用Java1.7封装的文件系统的通知回调机制,实现对指定目录的递归监控,避免每次全盘扫描性能太低的问题。

注意对于linux系统对于单个用户能够监听的inotify对象个数做了限制,一般是限制为8192,因此需要修改系统内核的配置:在/etc/sysctl.conf文件中,新增一行:fs.inotify.max_user_watches=1000000,表明将该限制修改为100万个。下次重启后会生效,如果希望当前立即生效,则需要执行命令:sysctl –p 。

对于WatchService,只监控当前目录的变化,当前目录下新增文件或者文件夹时,当前文件夹会有修改事件或者创建事件,但是再下一层的文件夹或者文件发生变更时,并不会有任何事件,因此如果要监控指定的文件夹,需要递归监控到最后一层。没有验证文件系统的notify机制对进程性能和文件系统性能的影响,在树莓派上面简单验证了下,能够非常及时的发现新增文件,进程CPU和内存也没有明显的增加。终于解决了每次都有依赖全盘扫描一遍文件才能发现新增的文件的问题。

具体代码请参见源码中的DirWatchService类。

| 1 分2 分3 分4 分5 分 (5.00- 9票) Loading ... Loading ... | 同时归档在:Jetty, WEB网络, 数据库, 软件技术 | 标签: , , |

基于Java WEB的本地照片管理系统jAlbum

最近搭建了基于树莓派3的家庭NAS系统,使用btsync工具将家里的各个终端:台式电脑、笔记本和家人的各个手机上面的图片等文件都集中备份到了NAS上面。发现各个设备上面的图片存放时并没有非常严谨的分类,并且有大量的重复照片,就想着做一个管理工具放在树莓派3上面,提供web访问接口,浏览器可以直接访问,生成一个简易相册,供各个终端查看和下载照片。 想到哪儿做到哪儿,并没有非常详尽的需求分析分析和软件设计。最终实现了如下功能:

  1. 定时扫描挂载在树莓派系统上面的硬盘的指定目录,收集所有的照片文件,jpg,png类型。建立一张sqlite3数据表,存储所有照片的路径、时间、指纹和长宽比等信息。系统也支持运行在目前各个主流的操作系统:MS Windows、MAC OS和Linux上面,免安装部署。
  2. 对1步骤生成的照片库根据照片的指纹值进行剔重,生成一张新的表,确保内容相同的照片只存一条记录。并且所有记录按照照片的拍摄时间顺序排列。
  3. 提供RESTful的接口供浏览器访问和获取相册。提供分年、月、日的视图。在前端呈现上面直接使用Java生成web页面,没有用一些高级的Marker组件。
  4. 后台定时产生任务,扫描新增的文件和重建数据表。
  5. 支持mp4视频文件的呈现。(需要在本机支持ffmpeg和ffprobe命令,下载ffmpeg工具:ffmpeg.org,如果是Windows系统,则需要把exe文件直接放入C:\Windows目录下;Linux系统可以直接使用发行版的软件仓库安装该软件。)
  6. 新增后台同步照片到AmazonS3服务功能。建议设置生命周期将桶内的数据转换到Glacier以节省开支。使用最小的成本防止照片数据丢失。
  7. 使用Face++服务实现人像识别,并按照人像对照片进行归集。开启该功能需要根据Face++的提示获取访问API的密钥对。

把项目代码开源出来,托管在github上面:jAlbum (https://github.com/shentar/jAlbum) 也可以从下面的链接下载编译好的各个版本的可执行文件包:
jAlbum_0.2.4.zip
jAlbum_0.2.3.zip
jAlbum_0.2.2.zip
jAlbum_0.2.1.zip

更新说明:

jAlbum_0.2.4 1、可靠性功能问题解决。2、性能提升。

jAlbum_0.2.3 1、增加人像识别和按照任务归集照片功能。

jAlbum_0.2.2 1、增加后台同步照片到AmazonS3服务端实现。2、修改若干重复文件检测bug。

jAlbum_0.2.1 1、解决问题:Chrome浏览器Ranges下载时第一个Range时不按照协议实现收取所有数据,最终在页面有多个Video时会导致浏览器挂死。单页面多个Video时,提取视频文件的缩略图呈现。

jAlbum_0.2.0  1、新增Video的支持,支持对MP4视频文件呈现;2、修正稳定性和功能细节的bug。

jAlbum_0.1.9  1、PC端浏览器,增加键盘翻页,左方向键翻上一页,右方向键翻下一页。 2、改进“照片发现”性能,最快在20秒内新增照片可以呈现到页面上。 3、其他bug解决。

jAlbum_0.1.8 1、优化照片隐藏逻辑,当隐藏的照片被移动或者删除后又添加时,也不会被显示出来。 2、适配移动终端浏览器,实现触控滑动照片翻页。 jAlbum_0.1.7 自动识别图片的旋转角度,在前端呈现时自动适应浏览器并旋转到正确的方向。

jAlbum_0.1.6 修正若干bug。使用按钮代替超链接来导航相册。

jAlbum_0.1.5 1、增加前端照片旋转功能。 2、完善照片删除功能。 3、解决稳定性bug。 jAlbum_0.1.4 新增删除照片功能。在单张照片显示的页面上面可以点击删除链接“删除”该照片,该照片之后不会再显示,当然照片还存在于磁盘中,只是不再显示。

jAlbum_0.1.3 1、增加文件系统监控,利用文件系统的notify机制及时处理新的文件变更; 2、不再定时全盘扫描,只在启动时进行全盘扫描; 3、定时根据base表的变更情况刷新辅助表及时呈现新增照片。

jAlbum_0.1.1 1、支持缩略图 2、优化编译脚本 3、增加配置文件

相册的效果图

0.2.4版本,根据人像识别结果进行照片归集页面截图:

faces

0.2.0版本截图: 主页: index

视频合集页面: video

0.1.1版本截图: snapshot

| 1 分2 分3 分4 分5 分 (5.00- 15票) Loading ... Loading ... | 同时归档在:Jetty, WEB网络, 数据库, 软件技术 | 标签: , , , , , |

Jetty 8长连接上的又一个坑

Jetty 8 长连接的超时断开连接的机制:超时连接机制针对IO传输过程中的数据阻塞时间超过一定阈值时,断开该连接。阻塞指当前处于数据传输阶段,但是连续指定时间内都没有发出或者接收到任何数据时,Jetty系统断开该连接。强调一下,只有在数据传输过程中才会有超时机制。在服务端处理已经收到的数据时是不会检测该超时时间的。

下面看一下具体的代码实现。在jetty 8.1.17版本中,由以下代码控制一个连接的空闲、非空闲和断开检查方法,在SelectChannelEndpoint类中:

阅读全文 »

| 1 分2 分3 分4 分5 分 (4.92- 53票) Loading ... Loading ... | 同时归档在:IO编程, Jetty, 软件技术 | 标签: , |

并发流程控制—CountDownLatch

假如有这样一个需求,当我们需要解析一个Excel里多个sheet的数据时,可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要提示解析完成。

在这个需求当中要实现主线程等待所有线程完成sheet的解析操作,最简单的做法是使用join。代码如下:

阅读全文 »

| 1 分2 分3 分4 分5 分 (4.75- 12票) Loading ... Loading ... | 同时归档在:多线程编程, 语言基础 | 标签: , , |

Java泛型:类型檫除、模板和泛型传递

Java泛型(generics)是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter)。声明的类型参数在使用时用具体的类型来替换。泛型最主要的应用是在JDK 5中的新集合类框架中。对于泛型概念的引入,开发社区的观点是褒贬不一。从好的方面来说,泛型的引入可以解决之前的集合类框架在使用过程中通常会出现的运行时刻类型错误,因为编译器可以在编译时刻就发现很多明显的错误。而从不好的地方来说,为了保证与旧有版本的兼容性,Java泛型的实现上存在着一些不够优雅的地方。当然这也是任何有历史的编程语言所需要承担的历史包袱。后续的版本更新会为早期的设计缺陷所累。 

开发人员在使用泛型的时候,很容易根据自己的直觉而犯一些错误。比如一个方法如果接收List<Object>作为形式参数,那么如果尝试将一个List<String>的对象作为实际参数传进去,却发现无法通过编译。虽然从直觉上来说,Object是String的父类,这种类型转换应该是合理的。但是实际上这会产生隐含的类型转换问题,因此编译器直接就禁止这样的行为。本文试图对Java泛型做一个概括性的说明。

阅读全文 »

| 1 分2 分3 分4 分5 分 (4.55- 11票) Loading ... Loading ... | 同时归档在:语言基础 | 标签: , , , |

Dijkstra算法求解最短路径分析

最短路径是图论算法中的经典问题。图分为有向图、无向图,路径权值有正值、负值,针对不同的情况需要分别选用不同的算法。在维基上面给出了各种不同的场景应用不同的算法的基本原则:最短路问题

针对无向图,正权值路径,采取Dijkstra算法

Dijkstra_Animation

如上图,是求a到b的最短路径,这里并不限定b节点,修改为到任意节点的路径,问题是完全一样的。

阅读全文 »

| 1 分2 分3 分4 分5 分 (4.92- 13票) Loading ... Loading ... | 同时归档在:算法数据结构 | 标签: , , |

如何编程实现 2 + 2 = 5?

Write a program that makes 2 + 2 = 5,看到这个题目,感觉很新颖,第一个答案就是用Java实现的。用上了Java中的整型实例池的概念。以前只看到过实例池导致两个对象的指针相同的问题,即

阅读全文 »

| 1 分2 分3 分4 分5 分 (4.20- 15票) Loading ... Loading ... | 同时归档在:语言基础 | 标签: |
返回顶部