1、JVM
jvm内存相关
内存模型
应用中静态变量、全局变量、局部变量、类、方法等对应jvm内存中的分配的具体区域(堆栈、堆(eden\from\to 老年代 、永久代))
GC类型
Minor GC针对新生代的GC
Major GC针对老年代的GC
Full GC 针对新生代、老年代、永久代三者的GC
垃圾回收
标记算法:标记(引用标记、root对象可达性标记)
垃圾回收算法:标记清除、标记整理、复制
复制 | 适用新生代,原因新生代存活率低(2%),可用较少预留空间用于复制,Eden 8+From 1->To 1,浪费10%内存。另外老年代可作担保。 |
标记整理- | 适用老年代,老年代不用复制算法原因:老年代存活率高,需要预留大量空间用于复制,(为了应对100%存活率,要预留50%内存)。 |
并发与并行对比
并行 | 垃圾收集多线程间并行 |
并发 | 垃圾收集线程与用户线程同时执行 |
吞吐量与停顿时间
吞吐量优先 | 高效利用CPU时间,适合后台运算,不需要太多交互的任务 |
停顿时间优先 | 用户响应时间短,适合于用户交互 |
jvm堆是垃圾收集器管理的区域,由于新生代、老年代、永久区域对象生命周期不一,所以采用分代回收策略
垃圾收集器:原理、基本步骤、解决的问题、使用场景(重点掌握cms和G1)
新生代
Serial 收集器:复制算法,Client默认
ParNew 收集器:复制算法,多线程并行,一般用于Server端
Parallel Scavenge:复制算法,多线程并行,关注吞吐量,有自适应调节
老年代
Serial Old收集器:标记整理
Parallel Old 收集器:标记整理
CMS 收集器:标记清除,回收线程与用户线程并发,
G1收集器
服务端应用,使命替换JDK1.5的CMS
特点
CMS:并发收集,低停顿
四个阶段 | STW | 干什么 | 时间开销 | 其他 |
初始标记 | 需要 | 标记GC Roots直接关联的对象 | 少 | |
并发标记 | GC Roots Tracing | 多 | 可与用户线程并发 | |
重新标记 | 需要 | 修正标记产生变动对象记录 | 少(多于初始标记) | |
并发清除 | 多 | 可与用户线程并发 |
CMS缺点:
对CPU资源敏感,因为并发占用部分线程,影响其他应用
无法处理浮动垃圾
用标记清除算法,有内存碎片的问题。有解决方案
G1:
并行 Parallel
并发 Concurrent
清理 scavenge 英 [ˈskævɪndʒ]
串行 serial 英 [ˈsɪəriəl] 连续的;连载的;顺序排列的;
内存调优命令
jps、jinfo、jstat、jmap、jstack(jmap常用于打印内存转存快照,查看内存使用情况及收集器信息;jstack常用于打印线程堆栈快照,分析当前线程,耗时、资源等待等问题)
内存调优工具
virtual
Java类加载
Java类的生命周期(类的加载过程):加载--验证--准备--解析--初始化--使用--卸载 (加载、验证、准备、初始化、卸载 这5个阶段顺序固定)
类加载器4种:
启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)、应用类加载器(Application ClassLoader)、自定义类加载器(User ClassLoader)
站在JVM只存在两种类加载器:
-
启动类加载器(
Bootstrap ClassLoader
):由C++
语言实现(针对HotSpot
),负责将存放在<JAVA_HOME>\lib
目录或-Xbootclasspath
参数指定的路径中的类库加载到内存中。 -
其他类加载器:由
Java
语言实现,继承自抽象类ClassLoader
。如:- 扩展类加载器(
Extension ClassLoader
):负责加载<JAVA_HOME>\lib\ext
目录或java.ext.dirs
系统变量指定的路径中的所有类库。 - 应用程序类加载器(
Application ClassLoader
)。负责加载用户类路径(classpath
)上的指定类库,我们可以直接使用这个类加载器。一般情况,如果我们没有自定义类加载器默认就是用这个加载器。
- 扩展类加载器(
双亲委派模型
双亲委派模型工作过程是:如果一个类加载器收到类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器完成。每个类加载器都是如此,只有当父加载器在自己的搜索范围内找不到指定的类时(即ClassNotFoundException
),子加载器才会尝试自己去加载。