JVM
发布日期:2021-10-23 14:13:25 浏览次数:5 分类:技术文章

本文共 2021 字,大约阅读时间需要 6 分钟。

目录

自动内存管理

运行时数据区

1400844-20190225161908559-79064033.png

线程私有的:虚拟机栈、本地方法栈、程序计数器

线程共享的:方法区、堆

程序计数器

线程私有的区域,指向本线程下一条要执行的字节码。不会抛出OOM异常

虚拟机栈

为执行java方法提供服务,如果栈深度超过允许范围,会抛出StackOverflowError;如果允许虚拟机栈扩展,在申请不到内存无法进行扩展时,会抛出OutOfMemoryError

本地方法栈

为执行native方法提供服务,类似于虚拟机栈,也会抛出StackOverflowError和OutOfMemoryError

对象实例和数组分配内存要在堆上进行。会抛出OOM异常。

堆可以位于物理上不连续的空间,逻辑连续即可。
GC的主要区域

方法区

保存虚拟机运行过程中加载的类信息、常量、静态变量等。

无法分配内存时,抛出OOM异常
这个区域的GC只要回收无用常量、卸载类

对象的创建过程

类加载、分配内存(如何保证原子性?)、内存清零、设置对象头、init

对象的内存布局:对象头、实例数据、对齐填充

垃圾回收机制

自动垃圾回收需要考虑的三个问题:

  • 回收哪些内存?对象存活判断(引用计数、可达性分析)
  • 什么时候回收?
  • 怎么回收?

垃圾回收算法

标记-清除

空间碎片

复制算法

Eden:From Survivor:To Survivor=8:1:1

复制操作效率低

标记-整理

分代算法

新生代和老年代采用不同算法

垃圾收集器

CMS

Concurrent Mark Sweep,顾名思义,采用标记清除算法回收垃圾,工作在老年代,多线程。工作过程如下:

  • 初始标记(Stop The World):标记与GC Roots直接相关的对象
  • 并发标记:根据上一阶段的标记遍历标记
  • 重新标记(STW):处理上一阶段用户线程对内存做的改动
  • 并发清除

CMS的缺点:

  • 对CPU资源非常敏感
  • 浮动垃圾:并发清除阶段由用户线程产生的垃圾内存
  • 空间碎片:标记清除算法的缺陷

G1

Garbage-First,多线程,新生代和老年代不再物理隔离,将内存分区Region,新生代和老年代都由一系列的Region组成,维护Region的优先队列,每次优先回收价值大的Region(因此叫GarbageFirst),标记整理算法

工作过程:

  • 初始标记:STW,标记与GC Roots直接相关的对象
  • 并发标记:遍历标记
  • 最终标记:STW,修正
  • 筛选回收:STW,对Region根据回收价值和成本进行排序,按照用户期望进行回收

GC 分为两类:minorGC和major/fullGC。

minorGC发生在新生代,快;
fullGC发生在老年代,慢一个数量级

内存分配策略

自动内存管理可以分为两个模块:如何分配内存、如何回收内存

堆的分区

总体分为新生代和老年代

新生代采用复制算法回收内存,因此又可以分为三个区:Eden、From Survivor、To Survivor

jvm分配内存的常用策略

下面来看jvm分配内存的常用策略:

  • 对象优先分配在Eden区
  • 大对象直接进入老年代,利用担保机制
  • 长期存活的对象进入老年代:每个对象都有年龄,如果对象熬过第一次minorGC并且进入了Survivor区,则age=1;以后每次存活,age++;当age达到一定值之后,对象晋升老年代

新生代对象内存分配过程:首先查看eden区空间是否够用,不够用则进行一次minor gc到survivor区,如果survivor区也不够用,通过分配担保机制转移到老年代。

JVM调优

类加载

类加载是如何把字节码转换成运行时数据

类加载的过程

类加载分为:

加载、验证、准备、解析、初始化、卸载

其中加载、验证、准备、初始化、卸载这5个过程必须按顺序开始(而不是“完成”)

加载

加载过程做了什么?

  • 根据类全限定名获取二进制字节码
  • 将字节码转换为运行时数据结构放在方法区
  • 创建该类对应的Class对象

验证

验证字节码是否符合虚拟机规范

准备

类变量分配内存、置零

解析

符号引用转化为直接引用

符号引用:字面量
直接引用:地址

初始化

类构造方法 <clinit>(),由类变量赋值语句和static块合成

类加载器

类和它的类加载器共同确立了这个类在jvm中的唯一性

双亲委派模型

类加载器具有层次化,从上往下依次是:

  • 启动类加载器
  • 扩展类加载器
  • 应用类加载器

双亲委派模型的工作过程:

如果一个类加载器收到了一个类加载请求,它首先会把加载任务交给上一层类加载器,如果上层类加载器不能完成类加载,则由自己完成类加载。

破坏双亲委派模型

  • 重写loadClass()方法
  • 线程上下文类加载器 Thread Context ClassLoader
  • OSGi

并发

转载于:https://www.cnblogs.com/darknessplus/p/10431448.html

转载地址:https://blog.csdn.net/weixin_30588827/article/details/98987070 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:使用WebSharper和F#开发移动应用
下一篇:TypeScript path mapping 编译后出现Cannot find module的问题

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年03月27日 08时06分06秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

windows8怎么下载python_win8怎么安装python 2021-06-24
linux猜数字程序,用linux实现猜数字小游戏源码 2019-04-21
linux下堆栈溢出实例,堆栈溢出在Linux上沉默? 2019-04-21
python创建nc文件_工具箱第2期 用python玩转NC 2019-04-21
拆分文件_文件拆分与合并 2019-04-21
开发优势_小程序开发优势好处有哪些 2019-04-21
4光影补丁_我的世界seus光影包 2019-04-21
aria手机下载_Aria2App 2019-04-21
汇编指令msr_ARM汇编:MRS和MSR指令 2019-04-21
慕课python第五周测试答案_中国大学MOOC(慕课)_python+_满分章节测试答案 2019-04-21
lsof查看占用高_lsof解决磁盘占用过高,查询却无大文件处理一例! 2019-04-21
python调用oracle过程 权限不足_oracle-存储过程提示 ORA-01031: 权限不足 2019-04-21
java ee6教程_Java EE 极简教程(六):框架的选择 2019-04-21
java io流过滤流_IO流分类详细介绍和各种字节流类介绍与使用 过滤流 字节流 2019-04-21
java预处理指令_Java程序员学C++_1_C++中的预处理命令 | 学步园 2019-04-21
java分词支持拼音_java 支持分词的高性能拼音转换工具,速度是 pinyin4j 的两倍... 2019-04-21
java中的%不对 如何处理_Java心得--异常及其处理 2019-04-21
java 上传速度计算_java常见3种文件上传速度对比和文件上传方法详细代码 2019-04-21
java 中区分月份_输入一年当中的月份,判断是哪个季节.(用java编写并且用到了import java.io.*;)... 2019-04-21
java 试图模版_图解Java设计模式之模板模式 2019-04-21