深入理解Java虚拟机(JVM的内容总结)

1.Java内存区域

1.1程序计数器

线程私有的,当同时进行的线程数超过CPU数或其内核数时,就要通过时间片轮询分派CPU的时间资源,不免发生线 程切换。这时,每个线程就需要一个属于自己的计数器来记录下一条要运行的指令。如果执行的是JAVA 方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为空。

1.2虚拟机栈

线程私有的,与线程在同一时间创建。管理JAVA方法执行的内存模型。每个方法执行时都会创建一个桢 栈来存储方法的的变量表、操作数栈、动态链接方法、返回值、返回地址等信息。栈的大小决定了方法 调用的可达深度(递归多少层次,或嵌套调用多少层其他方法,-Xss参数可以设置虚拟机栈大小)。栈 的大小可以是固定的,或者是动态扩展的。如果请求的栈深度大于最大可用深度,则抛出 stackOverflowError;如果栈是可动态扩展的,但没有内存空间支持扩展,则抛出 OutofMemoryError。

1.3本地方法栈

线程私有的,与虚拟机栈作用相似。但它不是为Java方法服务的,而是本地方法(C语言)。由于规范对这块没有强 制要求,不同虚拟机实现方法不同。

1.4方法区

线程共享的,用于存放被虚拟机加载的类的元数据信息,如常量、静态变量和即时编译器编译后的代 码。若要分代,算是永久代(老年代),以前类大多“static”的,很少被卸载或收集,现回收废弃常量和 无用的类。其中运行时常量池存放编译生成的各种常量。(如果hotspot虚拟机确定一个类的定义信息 不会被使用,也会将其回收。回收的基本条件至少有:所有该类的实例被回收,而且装载该类的 ClassLoader被回收)

1.5堆

存放对象实例和数组,是垃圾回收的主要区域,分为新生代和老年代。刚创建的对象在新生代的Eden 区中,经过GC后进入新生代的S0区中,再经过GC进入新生代的S1区中,15次GC后仍存在就进入老年 代。这是按照一种回收机制进行划分的,不是固定的。若堆的空间不够实例分配,则 OutOfMemoryError。

2.垃圾收集器

2.1判断对象是否已死

引用计数算法

根搜索算法(可达性分析)

2.2垃圾收集算法

标记-清除算法

复制算法

标记-整理算法

分代收集算法

2.3调优工具

常用调优工具分为两类,jdk自带监控工具:jconsole和jvisualvm,第三方有:MAT(Memory Analyzer Tool)、GChisto。

jconsole,Java Monitoring and Management Console是从java5开始,在JDK中自带的java监控 和管理控制台,用于对JVM中内存,线程和类等的监控。

jvisualvm,jdk自带全能工具,可以分析内存快照、线程快照;监控内存变化、GC变化等。 MAT,Memory Analyzer Tool,一个基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 GChisto,一款专业分析gc日志的工具。

2.4调优命令

jps,JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程。

jstat,JVM statistics Monitoring是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机 进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

jmap,JVM Memory Map命令用于生成heap dump文件。

jhat,JVM Heap Analysis Tool命令是与jmap搭配使用,用来分析jmap生成的dump,jhat内置了 一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看。

jstack,用于生成java虚拟机当前时刻的线程快照。

jinfo,JVM Configuration info 这个命令作用是实时查看和调整虚拟机运行参数。

2.5些JVM性能调优

1.设定堆内存大小 -Xmx:堆内存最大限制。

2.设定新生代大小。 新生代不宜太小,否则会有大量对象涌入老年代。

-XX:NewSize:新生代大小

-XX:NewRatio 新生代和老生代占比

-XX:SurvivorRatio:伊甸园空间和幸存者空间的占比

3.设定垃圾回收器。年轻代用 -XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC

3.类文件结构

1.加载

类的生命周期包括这几个部分,加载、连接、初始化、使用和卸载,其中前三部是类的加载的过程。

加载,查找并加载类的二进制数据,在Java堆中也创建一个java.lang.Class类的对象 。

连接,连接又包含三块内容:验证、准备、初始化。

1)验证,文件格式、元数据、字节码、符号 引用验证;

2)准备,为类的静态变量分配内存,并将其初始化为默认值;

3)解析,把类中的符 号引用转换为直接引用。

初始化,为类的静态变量赋予正确的初始值。

使用,new出对象程序中使用。

卸载,执行垃圾回收。

2.加载机制-双亲委派模式

双亲委派模式,即加载器加载类时先把请求委托给自己的父类加载器执行,直到顶层的启动类加载器.父类 加载器能够完成加载则成功返回,不能则子类加载器才自己尝试加载.

 优点:

1. 避免类的重复加载

2. 避免Java的核心API被篡改

3.Java的对象结构

Java对象由三个部分组成:对象头、实例数据、对齐填充。

对象头由两部分组成,第一部分存储对象自身的运行时数据:哈希码、GC分代年龄、锁标识状态、线 程持有的锁、偏向线程ID(一般占32/64 bit)。第二部分是指针类型,指向对象的类元数据类型(即对 象代表哪个类)。如果是数组对象,则对象头中还有一部分用来记录数组长度。

实例数据用来存储对象真正的有效信息(包括父类继承下来的和自己定义的)

对齐填充:JVM要求对象起始地址必须是8字节的整数倍(8字节对齐)

4.类加载器

实现通过类的权限定名获取该类的二进制字节流的代码块叫做类加载器。

主要有一下四种类加载器:

1. 启动类加载器(Bootstrap ClassLoader)用来加载java核心类库,无法被java程序直接引用。

2. 扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一 个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。

3. 系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过ClassLoader.getSystemClassLoader()来获取它。

4. 用户自定义类加载器,通过继承 java.lang.ClassLoader类的方式实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欲戴王冠♛必承其重

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值