client 与 server
Created|Updated|Java
|Word Count:168|Reading Time:1mins|Post Views:
client 模式
默认的jit编译器,c1。
默认的gc:serial-serial old。
需要更短的启动时间和初始堆大小,能做更保守的优化。
默认-Xms是1M,-Xmx是64M。
适合 GUI 程序。
server 模式
默认的jit编译器,c2。
默认的gc:ps-serial old即 PS MarkSweep(可以启用parallel old)。
需要更长的启动时间和更大的堆大小,能够做更有深度的优化。
默认-Xms是128M,-Xmx是1024M。
适合长时间运转的程序。
64 位JVM#
在64位 JVM 上有个 -d64 的模式,实际上就是禁止client模式单独启动,只允许server模式或者混合编译模式启动的模式。
Author: magicliang
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles
2021-10-09
JDK 的广泛分支
Oracle Hospot JDK java 8 特定版本以后就不再免费了。 现有的JDK8,2019.1之前的更新都可以免费获取正常使用。 Oracle JDK11是一个长期支持的版本,用于商业环境需要付费。 Azul Zulu builds of OpenJDK Zulu 是Azul公司基于OpenJDK发布的Java SE产品,它没有Oracle JDK对使用场景上的诸多限制,可以放心免费下载和使用。它的核心部分就是原汁原味的OpenJDK,没有任何额外的改动——Azul有时候也会对OpenJDK做bug fix,但这些都是通过提交回到OpenJDK去然后再进入到Zulu Java SE产品中的。它与“自己下载OpenJDK源码,自己build”的最大区别是:Azul会在每次发布Zulu产品之前进行充分的测试,build出来的二进制版本符合Java的兼容性测试;同时,Azul有与Oracle签订合作协议,在critical security fix的方面会比公开发布的OpenJDK源码要更早获得补丁,提前做好build与测试工作,基本上可以跟Oracle在同一时...

2019-09-02
Java 服务 OOM 排查全链路(Linux 内核 + JVM 工具链 + 问题分析)
Java 进程的 OOM 跨两层:Linux 内核的 OOM Killer 在物理内存或 cgroup limit 触及时 kill 进程,事后只能从 dmesg 还原;JVM 的 OutOfMemoryError 在堆/元空间/直接内存耗尽时抛异常,常带堆栈和 dump。两层工具栈不同:Linux 侧看 dmesg、cgroup、内核参数,JVM 侧看 jstat、jmap、jstack、arthas、JFR、gperftools。 一、Linux 层:OOM Killer 机制 Linux 内核有个 OOM (Out of Memory) Killer 的机制,可以在系统内存不足的时候,通过主动杀死一些进程来释放更多的内存空间。 很多时候,可以 ping 通一台服务器,但无法 ssh 上去,因为 sshd 被 OOM Killer 杀掉了。ping 能 ping 通,是因为处在内核态协议栈还能工作,发出回送报文。sshd 则因为是用户态进程,直接被干掉了。 OOM Killer 工作流程 OOM Killer 的完整工作流程如下: graph TD A[系统内存不足]...
2026-04-19
Java栈帧省略机制详解:为什么异常堆栈会消失?
引言:诡异的异常堆栈消失现象 线上服务报错时,你打开日志准备排查问题,却发现异常堆栈信息神秘消失了: 1java.lang.NullPointerException 只有短短一行异常类名,没有完整的堆栈跟踪。你可能会怀疑:是日志框架出问题了?还是被什么拦截器截断了? 其实,这是 JVM 的一个性能优化机制,叫做 OmitStackTraceInFastThrow(快速抛出时省略堆栈跟踪)。从 JDK 5 开始引入,默认启用。 本文将深入剖析这个机制的设计动机、工作原理、触发条件,以及如何正确应对。 一、问题场景:异常堆栈去哪了? 1.1 复现现象 用一段简单的代码就能复现: 123456789101112public class ExceptionOmitDemo { public static void main(String[] args) { String msg = null; for (int i = 0; i < 500000; i++) { try { ...
2017-10-27
基于栈的虚拟机
基于栈的虚拟机 全景导图 mindmap root((基于栈的虚拟机)) 核心架构 操作数栈 局部变量表 栈帧 执行机制 字节码指令 基于栈的运算 指令集简洁性 设计优势 可移植性 代码紧凑 实现简单 典型应用 JVM Python虚拟机 .NET CLR 模式总览 # 模式名称 一句话口诀 覆盖场景 1 栈式计算 数据流与控制流分离,操作数隐式传递 JVM字节码执行、表达式求值、递归调用 2 栈帧隔离 每个方法调用独立的执行上下文 方法调用、异常处理、线程隔离 3 指令紧凑 操作数位置编码在指令中,减少指令长度 字节码压缩、跨平台分发 问题定义 为什么选择基于栈的虚拟机架构,而非基于寄存器的架构?这种设计如何影响字节码的生成、执行效率以及跨平台可移植性? 核心概念 虚拟机架构分类 虚拟机按照指令集架构主要分为两类: 基于栈的虚拟机:指令不指定操作数的位置,操作数从栈顶弹出...
2026-02-07
JVM 的内存模型与线程
JVM 的内存模型与线程 Java 内存模型(Java Memory Model, JMM)定义了多线程环境下共享变量的访问规则,是理解并发编程的基石。本文从硬件架构出发,逐步深入到 JMM 的核心机制与实践模式。 mindmap root((JMM)) 硬件基础 CPU缓存层次 缓存一致性协议 JMM 抽象 主内存 vs 工作内存 八种内存操作 happens-before 关系 关键保证 原子性 可见性 有序性 实践工具 volatile synchronized final 模式总览 # 模式名称 一句话口诀 适用场景 1 写刷读清 写入即刷盘,读取先清空 volatile / unlock 后的可见性 2 顺序锁 同把锁内,串行执行 synchronized 临界区保护 3 偏序传递 A先于B,B先于C,则A先于C happens-before 链式推理 4 不可变安全 构造完成前...

2018-10-13
卡表和 RSet
卡表和 RSet 问题定义:为什么需要跨区域引用记录 JVM 垃圾收集器的核心工作之一是确定 live set——哪些对象仍然存活、不可回收。确定 live set 的标准做法是从 GC Roots(栈帧中的局部变量、静态字段等)出发,沿引用链遍历所有可达对象。 问题在于:当堆被划分为多个区域(代、Region)并且只回收其中一部分时,如何高效地找到从"不回收区域"指向"回收区域"的引用? 以 Young GC 为例:只回收新生代,但老年代中可能持有指向新生代对象的引用。如果不处理这些跨代引用,就会错误地回收仍被老年代引用的新生代对象。最朴素的做法是扫描整个老年代来找出这些引用——但老年代通常远大于新生代,这样做的代价过高,违背了分代收集"只回收一部分堆"的初衷。 卡表(Card Table)和 RSet(Remembered Set)正是为解决这个问题而设计的辅助数据结构。二者的关系并非互相替代,而是层次不同、协作互补:卡表是底层的脏标记机制,RSet 是建立在卡表之上的更高层索引结构。 核心概念速览 在深入细节之前,...
