1.运行时数据区域

1.程序计数器

当前线程执行字节码的行号指示器,字节码解释器工作通过改变这个计数器的值来选取下一条需要执行的字节码指令,每一个线程拥有独立的程序计数器,线程私有的内存

2.虚拟机栈

线程私有的内存,生命周期与线程相同,没有方法被执行会创建一个栈帧,存储局部变量表,操作栈等信息。

每一个方法被调用直至完成,对应一个栈帧在虚拟机栈中入栈到出栈的过程。

局部变量表所需的内存空间在编译器完成分配,调用方法时在帧中分配多大的局部变量完全确定,运行时不会改变该表大小。

线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。

若虚拟机栈动态扩展时无法申请到足够内存则会抛出OutOfMemoryError异常。

3.本地方法栈

与虚拟机栈作用类似,虚拟机栈为虚拟机执行Java方法服务,本地方法栈为虚拟机使用到的native方法服务

4.java堆

被所有线程共享的内存区域,虚拟机启动时创建,存放对象实例:所有对象实例及数组在堆上分配(JIT编译发展已不是那么绝对)。

java堆是垃圾收集器管理的主要区域,也被称为gc堆,可以根据分代收集算法细分为:新生代,老年代.也可以分为Eden空间、From Survivor空间、To Survivor空间.从内存分配分多个线程私有的分配缓存区。

java堆可以处于物理上不连续的内存空间中,逻辑上可以连续,可以扩展(通过-Xmx 与-Xms控制)。

无法扩展时抛出OutOfMemoryError异常。

5.方法区(hotSpot虚拟机使用永久代来实现方法区)

与java堆一样时各个线程共享的内存区域,存储已被虚拟机加载的类信息、常量、静态常量、及时编译器编译后的代码等数据。

垃圾回收在这个区域比较少出现,回收目标主要针对常量池的回收和对类型的卸载,回收条件苛刻,但比较有必要。

无法满足内存分配需求时抛出OutOfMemoryError异常。

运行时常量池

方法区的一部分。Class文件编译期生成的各种字面量和符号引用,类加载后存放到方法区的运行时常量池中。

除了保存class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行常量池中。

运行时常量池相对class文件常量池具有动态性,运行期间也可能将新的常量放入池中。

无法满足内存分配需求时抛出OutOfMemoryError异常。

6.直接内存

并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是会频繁使用,当本机总内存不足时也会抛出OutOfMemoryError异常。

jdk中新加如的nio 可以使用native函数库直接分配堆外内存,然后通过存储在java队中的directByteBuffer对象作用这块内存的引用进行操作。

程序计数器\虚拟机栈\本地方法栈 三个区域随线程而生,随线程而灭.java堆和方法区内存分配回收动态的。

2.对象访问

不同虚拟机不访问对象方式不同:

使用句柄访问

java堆中划分内存作为句柄池,reference存储对象句柄地址,句柄包含实例数据(实例池)和类型数据(方法区)的具体地址信息。

使用指针访问(hotSpot虚拟机)

java堆放置访问类型数据的相关信息,reference中直接存储对象地址。

句柄访问好处是reference中存储稳定的句柄地址,对象移动(常见垃圾收集时)值会改变句柄中的实例指针。

指针访问好处是访问快,节省指针定位的时间开销。

3.垃圾收集器与内存分配策略:

gc成为系统达到更高并发量的瓶颈时,需要手动调节及监控。

判断对象是否存活

1.引用计数算法:对象添加引用计数,有引用它时,计数加1,引用失效,计数减1,计数为0时不被使用;但是难以解决循环引用。

2.根搜索算法:GC root对象作为起点,向下搜索,搜索走过的路径称为引用链,当一个对象到gc root不可达,则可以回收。

gc root对象包括以下几种:虚拟机栈(栈帧中的本地变量表)、方法区(类静态属性、常量)、本地方法栈JNI(native方法)中的引用的对象。

四种引用:

强引用(不会回收被引用对象);

软引用(发生溢出异常前列入回收范围之中),SoftReference;

弱引用(被引用对象生存到下次垃圾收集前),WeakReference;

虚引用(不会对其生存时间构成影响,无法通过虚引用取得对象实例,目的收集器回收时收到通知),PhantomReference;

对象回收:经历两次标记过程

发现无引用链,第一次标记并筛选是否必要执行finalize()方法,若有必要则放置F-Queue队列中,由虚拟机创建低优先级线程执行。

GC对F-Queue队列中的对象第二次标记,若此次标记移除,则可以逃脱。

finalize()适合使用的“关闭外部资源”的工作,使用try-finally或者其他方式使用更好。

方法区回收(hotSpot虚拟机永久代)主要回收:废弃常量和无用的类。

垃圾收集算法

标记-清除算法:先标记需要回收的对象,标记完成后统一回收掉被标记的对象。

效率问题,标记清除过程效率不高。

空间问题,清除后产出大量不连续内存碎片。

复制算法,在标记清除算法上解决效率问题(新生代)

将内存按容量划分为相等两块,每次使用其中一块,当这一块内存用完后,将还存活着的对象复制到另外一块上,再把已使用过的内存空间清理掉。

回收新生代,新生代回收并不是按照1:1划分内存,将内存分为较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中的一块Survivor。

当回收时,将Eden和Survivor中还存活的对象一次性拷贝到另外的Survivor上,最后清理掉Eden和刚才用过的Survivor的空间(hotSpot虚拟机默认Eden和Survivor比例8:1)。

标记-整理算法,(老年代)

在标记清除算法上,标记后不直接清理可回收对象,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存

分代收集算法

根据对象的存活周期的不同将内存划分为几块,一般把java堆划分为新生代和老年代,这样可以根据各个年代的特点采用最适当的收集算法

垃圾收集器,不同虚拟机不同版本可能会有很大差别

Serial收集器,最基本最古老收集器,新生代收集器,单线程,简单高效,但是会停顿其他线程(Stop the world),直至收集结束。

ParNew收集器,新生代收集器,serial收集器多线程版,会暂停用户线程,但多线程进行GC回收。

Parallel Scavenge收集器,新生代收集器,使用复制算法,并行的多线程收集器,其主要目标是达到一个可控制的吞吐量,停顿时间越短越适合需要与用户交互的程序,而高吞吐量则可以高效利用cpu时间,适合后台运算而无需太多交互的任务。

Serial Old收集器Serial收集器老年代版本,单线程,使用标记整理。

Parallel Old收集器,老年代版本,多线程和标记整理算法,GC多线程且与用户线程同时进行。

CMS收集器,以获取最短回收停顿时间为目标的收集器,重视服务响应速度,基于标记-清除算法。

四步骤,初始标记、并发标记、重新标记、并发清除。优点:并发收集、低停顿。缺点:对cpu资源敏感、无法处理浮动垃圾、收集结束后会产生大量空间碎片。

G1收集器,基于标记-整理算法,不会产生空间碎片,可以精确控制停顿,收集范围为整个Java堆。

将java堆划分为多个大小固定的独立区域,跟踪区域内垃圾堆积程度,维护一个优先列表,根据允许的收集时间,优先回收垃圾最多的区域。

内存分配与回收策略

对象优先在java堆中的新生代Eden区中分配,若空间不足,发起一次Minor GC。

大对象(需要大量连续内存空间的java对象)直接进入老年代,避免Eden区及两个Survivor区发生大量复制。

长期存活的对象将进入老年代,虚拟机给每个对象定义了年龄计数器,每过一次Minor GC加一,默认加至15,将该对象晋升至老年代。

动态年龄判断,如果在Survivor空间相同年龄所有对象大小的综合大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代。

4.虚拟机性能监控与故障处理工具

命令行工具

jps:

列出正在运行的虚拟机进程,并显示虚拟机执行主类,及这些进程的本地虚拟机唯一id,例如:

D:\java\bin>jps10768RemoteMavenServer16224Jps11080

jstat:

显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,例如:

D:\java\bin>jstat -gc 10768S0C S1C   S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT48128.0 512.0 0.0 0.0 147456.0 11172.5 175104.0 10777.7 28032.0 26797.1 3456.0 3065.7 43 0.591 31 1.066 1.657

jinfo:

实时查看和调整虚拟机各项参数,例如查询pid为11996的各项参数:

D:\java\bin>jinfo -flags 11996

jmap:

用于生成堆转储快照(heapdump或dump文件),还可以查询finalize执行队列,堆和永久代详细信息,例如生成正在运行idea的dump快照文件:

D:\java\bin>jmap -dump:format=b,file=idea.bin 11996Dumping heap to D:\java\bin\idea.bin ...

Heap dumpfile created

jhat:

虚拟机堆转储快照分析,分析jmap生成的dump文件,例如分析上述例子中生成的idea.bin文件

D:\java\bin>jhat idea.bin

Reading from idea.bin...

Dumpfile created Thu Oct 10 13:59:41 CST 2019Snapshot read, resolving...

Resolving356454objects...

Chasing references, expect71dots...............

.........................

Eliminating duplicate references.................

.......................

Snapshot resolved.

Started HTTP server on port7000Server is ready.

然后在浏览器中输入http://localhost:7000/查看

jstack:

java堆栈跟踪工具,用于生成虚拟机当前时刻的线程快照。线程快照就是当期虚拟机内每一条线程正在执行的方法堆栈集合,定位线程出现长时间停顿的原因,例如:

D:\java\bin>jstack -l 11996

可视化工具

JConsole:Java监视与管理控制台

内存监控:用于受收集器管理的虚拟机内存(java堆和永久代)的变化趋势,可视化jstat命令

线程监控:可视化jstack命令

jvisualvm:多合一故障处理工具,一个代替上面所有

深入理解java虚拟机 新生代_深入理解java虚拟机:笔记相关推荐

  1. java虚拟机现状_深入理解java虚拟机的故障处理工具

    前言 本文主要给大家介绍的是java虚拟机的故障处理工具,文中提到这些工具包括: 名称 主要作用 jps JVM process Status Tool, 显示指定系统内所有的HotSpot虚拟机进程 ...

  2. java 异常机制_深入理解Java异常处理机制

    一.引子 try-catch-finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的"教训"告诉我,这个东西可不是想象中 ...

  3. java heap 内存_深入理解jvm之内存区域与内存溢出

    Java内存区域与内存溢出异常 运行时数据区域 程序计数器当前线程所执行的字节码的行号指示器 当前线程私有 不会出现OutOfMemoryError情况 java虚拟机栈线程私有,生命周期与线程相同 ...

  4. java 句柄池_深入理解JVM之Java对象的创建、内存布局、访问定位详解

    本文实例讲述了深入理解JVM之Java对象的创建.内存布局.访问定位.分享给大家供大家参考,具体如下: 对象的创建 一个简单的创建对象语句Clazz instance = new Clazz();包含 ...

  5. java画板抽象类_深入理解Java抽象类与接口

    基于抽象类与接口有太多相似之处且均体现着oop的抽象性,本文从以下几点谈谈对这两者的理解. 1.抽象类 2.接口 3.各自优缺点以及应用举例. 1.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象 ...

  6. java对象模型 指令_深入理解多线程(二)—— Java的对象模型

    上一篇文章中简单介绍过synchronized关键字的方式,其中,同步代码块使用monitorenter和monitorexit两个指令实现,同步方法使用ACC_SYNCHRONIZED标记符实现.后 ...

  7. java 线程 原子性_深入理解Java多线程与并发框架——Java内存模型与原子性、可见性、有序性...

    欢迎关注专栏<Java架构筑基>--专注于Java技术的研究与分享!Java架构筑基​zhuanlan.zhihu.comJava架构筑基--专注于Java技术的研究与分享! 后续文章将首 ...

  8. java在线编译器_什么是Java内存模型

    在知识星球中,有个小伙伴提了一个问题:有一个关于JVM名词定义的问题,说"JVM内存模型",有人会说是关于JVM内存分布(堆栈,方法区等)这些介绍,也有地方说(深入理解JVM虚拟机 ...

  9. java并发计数器_浅谈java并发之计数器CountDownLatch

    CountDownLatch简介 CountDownLatch顾名思义,count + down + latch = 计数 + 减 + 门闩(这么拆分也是便于记忆=_=) 可以理解这个东西就是个计数器 ...

最新文章

  1. 应届生想要获取web前端开发岗位?这份技能攻略,面试攻略别错过!
  2. 用chattr保护文件系统的安全
  3. Go - interface
  4. 妙用Telnet快速收发电子邮件(转载)
  5. 建议收藏!一文走遍机器学习的6个主流模型
  6. 为app录制展示gif
  7. 连接远程应用服务器appserver出错,Worklight 6.2:无法使用WL.Client.Connect连接到Worklight App Server...
  8. 心疼还在用Facebook的你一秒,Snapchat才是未来
  9. WSGI Middleware
  10. 互相关python程序_互相关(cross-correlation)及其在Python中的实现
  11. Concrete Mathematics A Foundation for Computer Science
  12. Nginx中 --- 内存池
  13. CMSIS RTOS API,内核通用API接口
  14. git checkout -b
  15. win10专业版和企业版的区别_Win10专业版和家庭版有什么区别?Win10家庭版和专业版区别对比...
  16. Error in driver during machine creation: Machine didn‘t return an IP after 120 seconds, aborting
  17. WiFi 运动,心跳,跌倒监测 (一)
  18. shell脚本、awk、sed用法
  19. 这些旅游类短视频账号在快手涨粉的总结
  20. java高级过滤器、baseServlet、log4j配置使用poi实现excel导入数据库

热门文章

  1. 国产三维gis软件的行业赋能情况
  2. ArcGIS栅格数据的空间分析讲解(上)
  3. 死磕Android_View工作原理你需要知道的一切
  4. python爬取猫眼电影
  5. deepin深度应用商店无法安装卸载软件解决方法
  6. 地市级公安交管融媒体中心运营模式研究
  7. kitti数据集_超全的3D视觉数据集汇总
  8. WPS二次开发简单示例
  9. 如何通过PHP语言设计出登录验证码(条型码)
  10. AVOD:Aggregate View Object Detection跑通(官方README小补充)