- 浏览: 169561 次
- 性别:
- 来自: 杭州
最新评论
文章列表
Twitter 推出的 Snowflake 是一个非常实用的分布式ID生成方案。它的默认设置中,各部分信息所占比特位比较有代表性,通常无需二次定制。但是对于 datacenter id 和 worker id 的维护需要各项目自行设计方案。
通常,datacenter id 是固 ...
生产环境不开启 DEBUG 级别的日志
对于部署到生产环境的程序,我们通常会将其日志级别设置为 INFO。DEBUG 级别的日志一般用于排查异常,而且通常数量较多。很少会有程序在生产环境默认开启 DEBUG 级别的日志。一个正常运行的程序,如果短时间内产生了大量日志,那么很可能是 logger 级别设置不正确。
我也见过有些程序员有意将本应归为 DEBUG 级别的日志用 INFO 级别记录,只是为了在出现业务异常时方便排查原因。当然这也会导致日志文件非常不直观,阅读体验非常差。在业务执行数量较大时,这些 INFO 日志甚至会“冲”掉目标日志。
但很多时候仅靠被持久化的业务数据记 ...
并发GC 之所以称为“并发”,是因为它的很多操作 与 应用程序的业务 是并发关系。 注意是“很多操作”而不是“所有操作”。所以提到它时会附带“Mostly”,即“Mostly Concurrent Collectors”。
Hotspot JDK 8 中 有 2个 并发GC:
CMS(Concurrent Mark Sweep Collector): 适用于需要更短的GC暂停时间,且可以忍受处理器资源被GC共享 的应用程序。 (其实这是 并发GC 的一般特征,G1 也是这样的。)
G1(Garbage-First Garbage Collector): 适用于大内存多 ...
【Java 8 GC 调优】并行GC
- 博客分类:
- Java
并行GC,也称为 吞吐量GC,是与 串行GC 类似的 分代GC。其主要区别在于,用多个线程加快垃圾收集速度。 可通过命令行选项 -XX:+UseParallelGC 启用 并行GC。默认情况下,使用此选项后,Minor 和 Major GC 都是并行执行,以进一步减少垃圾收集的开销。
在具有超过8个硬件线程的机器上,并行GC 会使用固定占比的数量作为GC线程数。 硬件线程数较大时,该占比为 5/8 。硬件线程数小于8时,GC线程数就是硬件线程数。在特定的平台上,该占比会降到 5/16 。可通过命令行选项指定 GC 线程数(稍后介绍)。 在单处理器机器上,因为并行执行(如,同步)的开销,并 ...
【Java 8 GC 调优】有哪些 GC
- 博客分类:
- Java
此节主要与 串行GC 相关。
3类 GC
Hotspot 有 3种 不同类型的 GC,每个 GC 都有不同的性能特征。
串行GC
串行GC 使用单线程执行所有垃圾回收工作。因为没有线程间通信开销,所以相对而言比较高效。 尽管它在多处理器机器上,对小数据集(上限100MB左右)的应用程序很有效,但它最适合单处理器的机器。因为它不能利用多处理器硬件的优势。 在某些硬件和操作系统上,串行GC 是默认选项。也可以通过 -XX:+UseSerialGC 显式启用。
并行GC(吞吐量GC)
并行GC 也称为 吞吐量GC。它以并行的方式执行 Minor GC,可以 ...
【Java 8 GC 调优】确定 “代” 的大小
- 博客分类:
- Java
很多参数会影响 “代” 的大小。下图说明了堆中“已提交空间”和“虚拟空间”之间的区别。JVM 初始化时会为堆预留整个空间。可以通过 -Xmx 选项指定这个预留空间的大小。如果参数 -Xms 的值比 -Xmx 小,那么不会把所有的预留空间都提交给 JVM。这些未提交的空间在图中被标为 “virtual”(虚拟空间)。堆的不同部分(新生代和老年代)可根据需要增长到虚拟空间的极限。
某些参数是堆中 一部分与另一部分 的比率。如,NewRatio 表示老年代与新生代的相对大小。
堆的总容量
以下关于 堆的增长和收缩 及 默认堆大小 不适用于并行GC。(可查看《并行GC》了解 ...
Jave SE 平台的一个优点是,它可以保护开发人员不受 内存分配 和 垃圾收集 复杂性的影响。但是当垃圾收集成为主要瓶颈时,了解这个隐藏实现的某些方面是很有用的。GC对应用程序使用对象的方式进行了假设。这些假设可以反映在可调参数中。可以在不牺牲抽象能力的情况下调整这些参数,以提高应用程序的性能。
当一个对象不能被程序中的任何指针访问时,会被认为是垃圾。最简单的GC算法会遍历每个可到达的对象。任何遗留的对象都被视为垃圾。这种方法所用的时间与活动对象的数量成正比。这使得大型应用程序无法维护大量活动数据。
JVM 融合了许多不同的GC算法。这些算法通过“代际收集”(Generationa ...
背景
在软件包中添加代码版本信息是许多组织使用的管理技巧。 这些信息在很多场景中可以发挥重要作用。 对于一些尚处于混沌状态的萌芽组织来说,这些信息几乎可以在排障过程中发挥灯塔的作用。
组织管理不善会引发很多“人祸”。 软件包覆盖版本发布?代码分支管理方法混乱?代码 tag 覆盖打?系统出了问题,不知道软件包是哪个分支、哪次提交构建的?
一个真实的项目
该项目基于 git 管理代码版本。 之前一直是通过自研的 CI 系统构建; 此 CI 系统会自动获取当前所构建代码的 git 信息,写入文件,添加到最终构建出的软件包中。 后来因为某些外部非技术原因,需要在另一套系统中构建 ...
(不知道把 Ergonomics 翻译成什么比较合适。) Ergonomics 是 “JVM” 和 “GC调优” 提高应用程序性能的过程(如,基于行为的调优)。JVM 根据所运行的平台提供了 GC、堆大小、运行时编译器 等方面的默认选择。这些选择符合不同类型应用程序的需求,可减少命令行(参数)调整。此外,基于行为的调优会动态调整堆大小,来满足应用程序的特殊行为。
本节介绍这些默认选择和基于行为的调优。在使用后续章节中描述的更详细的控制之前,先使用这些默认值。
GC、堆、运行时编译器 的默认选择
具有以下属性的机器会被定义为服务器类的机器:
2个或以上物理处理器
2G ...
【Java 8 GC 调优】引言
- 博客分类:
- Java
从小型桌面应用到大型服务器上的Web服务,有大量不同种类的应用程序使用了 Java SE 平台。为了支持多种多样的部署,Hotspot 这个 JVM 提供了多个垃圾收集器(GC),它们被设计成满足不同的需求。这是为了同时满足不同大小应用的重要组成部分。Java SE 会根据应用程序所运行的计算机类别,选择最合适的GC。但这可能并不是对每个应用的最优选择。用户,开发者,以及对性能目标有严格要求或有其它要求的管理员,可能需要显式地选择GC,并调整某些参数,来达到期望的性能水平。此文档提供了帮助执行这些任务的信息。首先,垃圾收集器的一般特性和基本调优选项会在 “Stop-the World” 系列 ...
【Java】被废弃的线程方法
- 博客分类:
- Java
原文:《Java Thread Primitive Deprecation》
为什么 Thread.stop 被废弃了?
Thread.stop 不安全。
Stop 一个线程会导致它释放所持有的锁(monitor)。(ThreadDeatch 抛出后会释放 monitor 的锁。)
这可能会导致之前被 monitor 保护的对象 ...
相关链接:
《MySQL自增变量auto_increment踩坑,重启后值丢失》
《Be Careful With MySQL's auto_increment. How We Ended Up Losing Data》
《AUTO_INCREMENT Handling in InnoDB》
背景描述
与相关链接《Be Careful...》中的案例很类似,某个业务系统中也有两张表,暂且称其为 pending_task 和 task_archive。它们的存储引擎都为 InnoDB;MySQL 版本为 5.7。
业务系统会先在 pending_task 表中创建 ...
黑白名单异常是 Dubbo 服务常见的问题。
异常示例:
com.alibaba.dubbo.rpc.RpcException: Forbid consumer 10.1.2.3 access service demo.service.DemoService from registry 10.1.2.3:2181 use dubbo version 2.8.4, Please check registry access list (whitelist/blacklist).
有时候问题原因并不是黑白名单,而是根本就没有服务提供者。 所以检查 ZooKeeper 中注册了哪些服务提 ...
相关链接:
《Reference counted objects》
《Why do we need to manually handle reference counting for Netty ByteBuf if JVM GC is still in place?》
《Are Java DirectByteBuffer wrappers garbage collected?》
一些基本信息与疑问
为什么 Netty 要采用人工操作的引用计数机制?
从 版本4 开始,Netty 中某些对象的生命周期管理是通过它们的引用计数实现的。 既然 JVM 有自己的垃圾回收机制 ...
在 Java NIO 编程实践中,很多人都会选择 Netty 作为基础框架,而不是直接用 JDK 原生的 NIO API。 因为 JDK 原生的 NIO 框架内容过于繁杂、学习成本高、补齐可靠性的工作量和难度都很大、还有一些bug。 其中一个著名的bug就是 epoll Selector 空转问题。
相关Bug单
《JDK-6670302 : (se) NIO selector wakes up with 0 selected keys infinitely [lnx 2.4]》
《JDK-6403933 : (se) Selector doesn't block on Sel ...