Java
文章平均质量分 79
一个被IT搞的
这个作者很懒,什么都没留下…
展开
-
【序列化】Kryo 的几种常见序列化实现方式,及其兼容性
Kryo 是啥Kryo是Java生态中的一种序列化框架。许多软件组织在使用Dubbo(Dubbox)这套RPC框架时,经常会搭配使用 Kryo 作为其序列化方案。Kryo本身自带了很多针对 Java 原始数据类型 和 JDK常见类型的 序列化实现(如,DefaultSerializers)。它的姐妹工程 Kryo-Serializers 还提供很多额外的序列化实现。Kryo 常见序列化实现方式序列化/反序列化的兼容性问题序列化/反序列化 最主要的是关注对象内容。大多数场景中,我们只会序列化对原创 2020-06-08 21:12:02 · 4658 阅读 · 0 评论 -
【Java 8 GC 调优】其它考量点
本节介绍影响GC的其它情况。Finalization 和 弱引用、软引用 及 幻象引用有些应用程序会通过 Finalization 和 弱引用、软引用 及 幻象引用 与 GC 交互。这些特性会在 Java 编程语言级别造成性能问题。一个例子就是 依赖 Finalization 关闭文件描述符。...原创 2020-03-06 13:35:44 · 224 阅读 · 0 评论 -
【Java 8 GC 调优】Concurrent Mark Sweep(CMS)
CMS(Concurrent Mark Sweep collector)适合的应用程序是“偏好更短的 GC暂停时间,且能忍受在应用运行期间 GC 分享处理器资源”。其典型的应用特征是,有一些相对较大的 “长寿命”数据,且运行在 2个或更多 处理器的机器上。但是,对于任何有 “低暂停时间” 需求的应用程序,都应该考虑此收集器。可通过命令行选项 -XX:+UseConcMarkSweepGC 来启用...原创 2020-02-18 14:09:41 · 3196 阅读 · 1 评论 -
【Java 8 GC 调优】Garbage-First(G1)
G1 是一个 服务器风格(Server-Style)的垃圾收集器。其适用目标是具有大内存的多处理器计算机。它试图在实现高吞吐量的同时,高概率地满足 GC暂停时间 目标。整个堆操作,如 全局标记,与业务线程同时运行。这可以防止 中断的发生概率 与 堆或存活数据大小 成比例。G1 通过几种技术实现了 高性能 和 暂停时间 目标。堆被划分成一些大小相等的区域,每个区域都是一片连续的虚拟内存(vi...原创 2020-02-19 10:37:57 · 674 阅读 · 0 评论 -
【Java 8 GC 调优】G1 调优
此节介绍如何调整和优化G1,以进行评估、分析和性能测试。如《G1》所述,G1 是一个 分区、分“代” 的收集器,这意味着Java对象堆被分成了许多大小相等的区域。JVM启动时会设置区域大小。区域大小取决于堆大小,从 1MB 到 32MB。目标是不超过 2048 个区域。Eden、Survivor 和 老年代 是逻辑集合,且不是连续的。G1 有一个尝试达成的 暂停时长 目标(这是一个软实时目...原创 2020-02-20 16:28:49 · 3489 阅读 · 0 评论 -
【Arthas】运行时调整 Java 程序的 logger 日志级别
生产环境不开启 DEBUG 级别的日志对于部署到生产环境的程序,我们通常会将其日志级别设置为 INFO。DEBUG 级别的日志一般用于排查异常,而且通常数量较多。很少会有程序在生产环境默认开启 DEBUG 级别的日志。一个正常运行的程序,如果短时间内产生了大量日志,那么很可能是 logger 级别设置不正确。我也见过有些程序员有意将本应归为 DEBUG 级别的日志用 INFO 级别记...原创 2020-01-15 09:16:07 · 2155 阅读 · 0 评论 -
【Java 8 GC 调优】并发GC(Mostly Concurrent Collector)
并发GC 之所以称为“并发”,是因为它的很多操作 与 应用程序的业务 是并发关系。注意是“很多操作”而不是“所有操作”。所以提到它时会附带“Mostly”,即“Mostly Concurrent Collectors”。Hotspot JDK 8 中 有 2个 并发GC: CMS(Concurrent Mark Sweep Collector): 适用于需要更短的GC暂停时间,...原创 2020-01-15 09:15:56 · 908 阅读 · 0 评论 -
【Java 8 GC 调优】并行GC
并行GC,也称为 吞吐量GC,是与 串行GC 类似的 分代GC。其主要区别在于,用多个线程加快垃圾收集速度。可通过命令行选项 -XX:+UseParallelGC 启用 并行GC。默认情况下,使用此选项后,Minor 和 Major GC 都是并行执行,以进一步减少垃圾收集的开销。在具有超过8个硬件线程的机器上,并行GC 会使用固定占比的数量作为GC线程数。硬件线程数较大时,该占比为 ...原创 2020-01-15 09:15:47 · 1810 阅读 · 0 评论 -
【Java 8 GC 调优】有哪些 GC
此节主要与 串行GC 相关。3类 GCHotspot 有 3种 不同类型的 GC,每个 GC 都有不同的性能特征。串行GC串行GC 使用单线程执行所有垃圾回收工作。因为没有线程间通信开销,所以相对而言比较高效。尽管它在多处理器机器上,对小数据集(上限100MB左右)的应用程序很有效,但它最适合单处理器的机器。因为它不能利用多处理器硬件的优势。在某些硬件和操作系统上,串...原创 2020-01-15 09:15:38 · 343 阅读 · 0 评论 -
【Java 8 GC 调优】确定 “代” 的大小
很多参数会影响 “代” 的大小。下图说明了堆中“已提交空间”和“虚拟空间”之间的区别。JVM 初始化时会为堆预留整个空间。可以通过 -Xmx 选项指定这个预留空间的大小。如果参数 -Xms 的值比 -Xmx 小,那么不会把所有的预留空间都提交给 JVM。这些未提交的空间在图中被标为 “virtual”(虚拟空间)。堆的不同部分(新生代和老年代)可根据需要增长到虚拟空间的极限。某些参数是堆中 一...原创 2020-01-15 09:15:28 · 296 阅读 · 0 评论 -
【Java 8 GC 调优】“代”(Generation)
Jave SE 平台的一个优点是,它可以保护开发人员不受 内存分配 和 垃圾收集 复杂性的影响。但是当垃圾收集成为主要瓶颈时,了解这个隐藏实现的某些方面是很有用的。GC对应用程序使用对象的方式进行了假设。这些假设可以反映在可调参数中。可以在不牺牲抽象能力的情况下调整这些参数,以提高应用程序的性能。当一个对象不能被程序中的任何指针访问时,会被认为是垃圾。最简单的GC算法会遍历每个可到达的对象。任...原创 2020-01-15 09:15:08 · 254 阅读 · 0 评论 -
【Maven 插件】为 jar 包添加代码版本信息 —— git-commit-id-plugin
背景在软件包中添加代码版本信息是许多组织使用的管理技巧。这些信息在很多场景中可以发挥重要作用。对于一些尚处于混沌状态的萌芽组织来说,这些信息几乎可以在排障过程中发挥灯塔的作用。组织管理不善会引发很多“人祸”。软件包覆盖版本发布?代码分支管理方法混乱?代码 tag 覆盖打?系统出了问题,不知道软件包是哪个分支、哪次提交构建的?一个真实的项目该项目基于 git 管理代...原创 2020-01-15 09:14:57 · 2786 阅读 · 0 评论 -
【Java 8 GC 调优】Ergonomics
(不知道把 Ergonomics 翻译成什么比较合适。)Ergonomics 是 “JVM” 和 “GC调优” 提高应用程序性能的过程(如,基于行为的调优)。JVM 根据所运行的平台提供了 GC、堆大小、运行时编译器 等方面的默认选择。这些选择符合不同类型应用程序的需求,可减少命令行(参数)调整。此外,基于行为的调优会动态调整堆大小,来满足应用程序的特殊行为。本节介绍这些默认选择和基...原创 2020-01-14 09:42:18 · 2557 阅读 · 0 评论 -
【Java 8 GC 调优】引言
从小型桌面应用到大型服务器上的Web服务,有大量不同种类的应用程序使用了 Java SE 平台。为了支持多种多样的部署,Hotspot 这个 JVM 提供了多个垃圾收集器(GC),它们被设计成满足不同的需求。这是为了同时满足不同大小应用的重要组成部分。Java SE 会根据应用程序所运行的计算机类别,选择最合适的GC。但这可能并不是对每个应用的最优选择。用户,开发者,以及对性能目标有严格要求或有其...原创 2020-01-14 09:41:59 · 181 阅读 · 0 评论 -
【Java】被废弃的线程方法
原文:《Java Thread Primitive Deprecation》为什么 Thread.stop 被废弃了?Thread.stop不安全。 Stop 一个线程会导致它释放所持有的锁(monitor)。(ThreadDeatch 抛出后会释放 monitor 的锁。) 这可能会导致之前被 monitor 保护的对象处于 不一致的状态,并被其它线程看到。也就是...原创 2020-01-14 09:41:38 · 563 阅读 · 0 评论 -
Netty 引用计数对象
相关链接: 《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 collect...原创 2020-01-14 09:40:03 · 188 阅读 · 0 评论 -
Java NIO epoll 空转问题 + Netty 解决方法
.在 Java NIO 编程实践中,很多人都会选择 Netty 作为基础框架,而不是直接用 JDK 原生的 NIO API。因为 JDK 原生的 NIO 框架内容过于繁杂、学习成本高、补齐可靠性的工作量和难度都很大、还有一些bug。其中一个著名的bug就是 epoll Selector 空转问题。相关Bug单 《JDK-6670302 : (se) NIO select...原创 2020-01-14 09:39:53 · 2324 阅读 · 0 评论 -
Reator 模式 + Netty 线程模型 + 最佳实践建议
Reactor 模式大部分网络框架的设计都基于 Reactor 模式。这种模式基于事件驱动,特别适合处理大量的 IO 事件。根据线程数量,我们可以将 Reactor 模式大致分为以下3种(以服务端实现为例):单线程 Reactor单个 Reactor 线程负责对TCP链路读写数据和编解码(包括执行业务逻辑)。(很多人把该模式称为 “1 - 1”。其实这种称呼并不贴切。...原创 2020-01-14 09:39:12 · 720 阅读 · 0 评论 -
Netty 简介 - 高性能原理 + 关键组件模型
Netty > java.nio + java.netNetty 是一个 NIO 框架。它的设计强调了“分离关注点”(Separation Of Concerns)。它通过事件机制,将业务逻辑与无关的技术逻辑隔离,通过抽象层填补 基础平台 和 业务开发 之间的鸿沟。Netty 极大地简化了网络编程(如,TCP/UDP socket 服务器)。可以利用它更快速容易地开...原创 2020-01-14 09:38:53 · 179 阅读 · 0 评论 -
【Dubbo】Dubbo 服务序列化兼容性技巧 —— CompatibleFieldSerializer
序列化兼容技巧 之 指定序列化方式:CompatibleFieldSerializer因为性能出色,Kryo 经常被选为Dubbo服务的序列化方案。在序列化Java对象时,Kryo 默认使用 FieldSerializer 类进行序列化。但为了增强兼容性,我们一般会显式指定使用 CompatibleFieldSerializer。使用方式就是在 API jar 包中的类上...原创 2020-01-13 16:04:21 · 2162 阅读 · 0 评论 -
Spring Bean 作用域
常见的 4 种作用域Spring Bean 的默认作用域是 Singleton。一般通过注解 @Scope 自定义Bean的作用域。 Singleton 整个应用中,只创建一个实例。(默认) ConfigurableBeanFactory.SCOPE_SINGLETON Prototype 每次注入或通过Spring Application Context 获取时,都...原创 2020-01-13 16:00:33 · 1134 阅读 · 0 评论 -
Spring Bean 生命周期 + 循环依赖解决方法
Bean 创建过程自定义的初始化方法通常通过 @Bean 注解的 initMethod 指定(不推荐XML形式的配置方式)。Bean 销毁过程自定义的销毁方法类似自定义的初始化方法。通常通过 @Bean 注解的 destoryMethod 指定(不推荐XML形式的配置方式)。Bean循环依赖解决方法通过构造方法注入依赖 —— 失败...原创 2020-01-13 15:56:41 · 919 阅读 · 0 评论 -
【Java核心-基础】ConcurrentHashMap 高效地线程安全简介
JDK提供了一些线程安全的集合。有粗粒度 synchronized 的集合。如,Hashtable、Collections.synchronizedXxx 包装的集合。有细粒度,基于分离锁实现的集合。如,ConcurrentHashMap。通常,并发包中提供的容器性能远优于早期的简单同步实现。为什么需要ConcurrentHashMap?HashMap 不是线程安全的。在...原创 2020-01-13 15:56:37 · 97 阅读 · 0 评论 -
【Java核心-安全基础】编写安全的Java代码
实现安全的Java代码,需要从功能设计到实现细节,都充分考虑可能的安全影响。以消耗系统资源为目的的攻击是很常见的方式。CPU、线程、内存、文件描述符、数据库连接、再入锁等各种资源都可能成为攻击者消耗的目标。常见代码问题数值运算溢出如:Java代码 if(a+b<c){ ... } a+b 可能超出上限。改成 a&...原创 2020-01-13 15:55:55 · 319 阅读 · 0 评论 -
【SSL证书校验】Java Client 忽略对服务端的SSL证书校验
背景在某些特殊的项目中虽然使用了HTTPS,但其证书管理又不是采用常规模式,如服务端用了个自签名的证书。很多组织的内部项目因为各种原因采用了这种方式。(先不深挖这种模式的利弊)这种情况下,大多数HTTP客户端工具或框架都默认禁止此类证书。为了让客户端忽略SSL证书校验,需要额外的客户端代码设置。实现方式本文针对两种Java常见HTTP客户端请求方式,提供实现样例...原创 2020-01-13 15:55:44 · 4940 阅读 · 0 评论 -
【异常】JVM 获取 Linux 时间错误(相差12小时)
.问题有两台Linux机器:date 命令查看时间相同通过 date 命令查看时间,发现两台机器区域语言和时间都相同:JVM获取系统时间相差12小时通过最基本的java代码 new Date() 获得时间,发现两台机器的系统时间相差12小时。其中一台输出的时区与上述date命令相同,都是东八区(CST,中国标准时间)。另一台输出的时区与date命令不符,是...原创 2020-01-13 15:55:41 · 2559 阅读 · 1 评论 -
【Dubbo】序列化异常—— com.esotericsoftware.kryo.KryoException: Buffer underflow
Dubbo服务通常依赖一个jar包来表示服务签名,其中包含了服务的接口定义。服务的提供者(服务端)需实现这些接口;服务的调用者(客户端)可以通过这些接口调用服务。问题此文提到的异常 “com.esotericsoftware.kryo.KryoException: Buffer underflow” 通常是因为服务端和客户端持有的jar包版本号相同,但实际内容不同,导致序列化异常。...原创 2020-01-13 15:55:31 · 5537 阅读 · 0 评论 -
【Java核心-安全基础】Java的安全机制
任何可以用来绕过系统安全策略限制的缺陷都是安全漏洞。构建安全可靠的服务需要通过整体性的安全设计和综合性的防范手段。Java的安全机制1. 运行时安全机制字节码校验类加载过程中,字节码验证,防止不合规的代码影响JVM运行或载入恶意代码。如,自行编译String类替换JDK的String类就无法通过类加载。Class Loader 隔离代码 应用无法获...原创 2020-01-13 15:55:19 · 1294 阅读 · 1 评论 -
【Java核心-进阶】类加载
Java类加载的三个阶段《Loading, Linking, and Initializing》加载(Loading)将Java字节码数据读取到JVM中,并映射为 Class 对象。数据源可以是 jar文件、class文件或网络数据源。用户可以实现自己的类加载器来自定义加载过程。链接(Linking)把原始的类定义信息平滑地转化入JVM。分为三个子...原创 2020-01-12 19:54:26 · 88 阅读 · 0 评论 -
【Java核心-进阶】CAS(compare-and-swap)
CAS简介CAS(compare-and-swap)是一种对数据进行原子性操作的技术。它提供了一系列操作指令用于读取数值,或并发修改。它是Java并发中所谓 “lock-free” 机制的基础。CAS的底层依赖于CPU提供的指令。如,x86 CPU 的 cmpxchgCAS使用方式AtomicIntegerAtomicInteger使用了CAS技术,它底...原创 2020-01-12 19:54:16 · 209 阅读 · 0 评论 -
【Java核心-进阶】运行时动态生成Java类
.技术上可行的方式生成源码文件 -> 编译源码 -> 加载类方式1:javac编译可以用 ProcessBuilder 这个类启动 javac 进程,编译源码文件方式2:Java Compiler API 编译JDK中的 Java Compiler API 提供了与 javac 对等的编译能力。(示例:InMemoryJavaCompiler)...原创 2020-01-13 15:55:10 · 887 阅读 · 0 评论 -
【Java核心-进阶】线程池(Executor)
线程池主要类概览ExecutorExecutor的初衷是将 任务提交 和 任务执行的细节 解耦。只有一个提交任务的方法:Java代码 voidexecute(Runnablecommand); ExecutorService虽然我们习惯将ExecutorService称为线程池,但它并不是简单的线程“池”。它提供了比较全面的 线程管理...原创 2020-01-12 19:47:16 · 158 阅读 · 0 评论 -
【Java源码解读——释疑】为什么将类成员变量复制为方法本地变量
.参考: 《In ArrayBlockingQueue, why copy final member field into local final variable?》 《Performance of locally copied members ?》 JDK源码中经常会出现一种代码模式:将类成员变量复制到方法本地变量上。如:String.compareTo() ...原创 2020-01-12 19:47:00 · 217 阅读 · 0 评论 -
【Java核心-进阶】并发队列
JDK并发队列概览典型特性Queue vs DequeDeque 是 双端队列,它的侧重点是支持队列首尾都能添加删除元素。Deque 提供了更多方法,如典型的 offerLast(e),pollLast()Blocking vs 非BlockingBlocking表示队列提供了“等待性”相关操作。如,获取元素时会等到队列中有元素时再返回;添加元素时...原创 2020-01-12 19:46:51 · 105 阅读 · 0 评论 -
【Java】Java Memory Model FAQ
Java的内存模型中某些“奇技淫巧”,或者说是“巫术”,对于某些特定场景是非常关键的。从某种角度而言,我们可以直接称之为“缺陷”;“让语言的使用者无需关心底层实现”是编程语言发展的重要方向之一。“程序语义简单直观”也是 JSR 133 的目标之一。如,JDK CopyOnWriteArrayList.set() 方法中对 volatile 字段的处理方式就涉及了非常晦涩的内存模型特性。(详...原创 2020-01-12 19:46:17 · 101 阅读 · 0 评论 -
【Java核心-进阶】并发工具包——线程安全的 List、Map、Set
.三大并发类:Concurrent、CopyOnWrite、BlockingJava并发包中的集合从线程安全实现方式而言可分为三类:Concurrent、CopyOnWrite、Blocking。 Concurrent 类的集合基于 lock-free 的方式实现。严格来说,它们是真正的并发。适合实现较高的吞吐量。 CopyOnWrite 类的集合顾名思义,会在该变集合的操...原创 2020-01-12 19:46:10 · 680 阅读 · 0 评论 -
【Java Web】Filter vs Interceptor
我们说的 Filter 和 Interceptor 是啥? Filter:javax.servlet.Filter Interceptor:org.springframework.web.servlet.HandlerInterceptor 参考: 《Filter vs Interceptor》 《Difference between Interceptor a...原创 2020-01-12 19:45:51 · 126 阅读 · 0 评论 -
【Dubbo】最常用的dubbo性能调优点
这里只提供最常用的Dubbo服务调优点简要说明,旨在用更小的成本,获得更多性能收益。这里的“成本”是综合性的,包括 时间、硬件、技术学习等。即,此指南追求“实用性”。“最常用”、“简要”也意味着这不是一份全面的Dubbo调优指南。但是对于绝大多数微服务而言,足矣。再继续调优,很可能就是涉及具体的业务逻辑流程。dubbo:protocolthreadpool 和 threa...原创 2020-01-10 13:50:19 · 1145 阅读 · 1 评论 -
Spring i18n 国际化样例
网上有很多Spring国际化的样例,但是缺少详细的样例。特别是国外网上很多是Spring MVC(Web)之类的样例,而国内稍具规模的软件开发组织都采用前后端分离的模式,所以几乎很少有易于模仿的 纯基础Spring国际化 样例。1. 创建 Spring Boot 工程1.1 Maven依赖此示例以Command Line方式运行,所以依赖 spring-boot-starter,而不是...原创 2020-01-10 13:50:10 · 373 阅读 · 0 评论 -
【Java核心-进阶】Semaphore、CountDownLatch、CyclicBarrier、Phaser
Java并发包中有很多可以实现同步的结构。以下几种就属于典型的“非显式”锁: Semaphore:Java版本的信号量实现。 CountDownLatch:允许一个或多个线程等待某些操作完成。 CyclicBarrier:允许多个线程等待达到某个屏障。 Phaser:分阶段地等待多个线程达到某个屏障。 CountDownLatch vs CyclicBarr...原创 2020-01-10 13:49:48 · 364 阅读 · 0 评论