源文档:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/index.html

JVM体系结构     方法区,类加载器,堆,Java栈,本地方法栈,程序计数器,执行引擎,PC寄存器。

类加载器:

• 启动类加载器 (Bootstrap Bootstrap)

• 扩展类加载器 (Extension Extension Extension)Java Java
• 应用程序类加载器应用程序类加载器 应用程序类加载器 (AppClassLoader AppClassLoader AppClassLoader ) Java
      也叫系统类加载器,加载当前应用的classpath的所有类的所有类
• 用户自定义加载器JJava.lang.ClassLoader的子类,用户可自定义

类的加载步骤:

  • 效验:检查class文件的正确性,安全性
  • 准备:为类变量分配存储空间并设置类变量初始值,类变量随类型信息存放在方法区中,生命周期很长,使用不当和容易造成内存泄漏。
  • 解析:jvm将常量池内的符号引用转换为直接引用

分析ClassLoader.loadClass和Class.forName的区别

反射实现的方式及原理?

PC寄存器

  • 程序计数器是一块较小的内存空间 程序计数器是一块较小的内存空间,当前线程所执行的字节码是当前线程所执行的字节码是当前线程所执行的字节码的行号指示器
  • 程序计算器处于线独占区
  • 如果线程执行的是 java方法,记录的是正在执行虚拟的字节码指令的地址,如果是native方法,这个计数器的值为undefined

栈区:

  • 栈也叫内存 ,主管 Java 程序的运行 ,是在线程创建时创建 ,它的生命期是跟随线程,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题 ,只要线程一结束该栈就Over 生命周期和线程一致,是线程私有的 。8种基本类型的变 量+对象的引用变量 +实例方法都是在函数的栈内存中分配

栈存储什么 ?

  • 局部变量表 :输入参数和出以及方法内的变量 类型;局部表在编译期间完成分配,当进入一个方法时这帧中多少内存是固定的
  • 栈操作( Operand Stack ):记录出栈、入的操作;
  • 动态链接
  • 方法出口
  • 栈溢出 StackOverflowError,OutOfMemory

方法区:

Method Area 方法区是被所有线程共享 ,所有字段和方法节码 ,以及一些特殊方法如构造函数 ,接口代码也在此定义 。简单说 ,所有定义的方法信息都保存在该区域 ,此区属于共享间类信息 类的版本字段方法接口

  • 静态变量
  • 常量
  • 类信息 (构造方法 /接口定义 )
  • 运行时常量池

方法区与永久代

方法区永久存储区是一个常驻内域,用于放 JDK 自身所携带的 Class,Interface 的元数据,也就是说它存储运行环境必须类信息被装载进此区域不会被垃圾回收器掉的,关闭JVM才会释放此区域所占用的内存。如果出现java.lang.OutOfMemoryError:PermGen space,说明是Java 虚拟机对永久代Perm内存设置不够。一般出现这种情况,都是程序启动需要加载大量的第三方jar包。

  • Jdk1.6 及之前: 有永久代 , 常量池 1.6 在方法区
  • Jdk1.7 : 有永久代,但已经逐步“去”,常量池 1.7 在堆
  • Jdk1.8 及之后: 无永久代,常量池 1.8 在元空间

常量池问题<待续>

 堆:

一个 JVM 实例只存在一个堆内,堆内存的大小是可以调节的.类加载器读取了文件后,需要把类,方法,常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器,堆内存分为三部:

  • Permanent Space Permanent Space  新生区   Young/NewYoung
  • Tenure generation space 养老区 Old/ Tenure Old
  • Permanet  Space 永久区   Perm

堆JDK7和JDK8之间的关系和差异

对象的创建流程

堆,栈,方法区的交互关系

内存的分配策略:

  • 优先分配Eden区
  • 大对象直接分配到老年代 -XX:PretenureSizeThreshold
  • 长期存活的对象分配老年代 -XX:MaxTenuringThreshold=15
  • 空间分配担保 -XX:+HandlePromotionFailure

  检查老年代最大可用的连续空间是否于历次晋升到年代对象的平均大小。

  • 动态对象年龄如果在Survivor空间中相同年龄所有对象大小的总和于 Survivor空间的一半,年龄大于或等该的对象就可以直接进入老代

-XX:TargetSurvivorRatio

性能调优

如何判断对象为垃圾对象?

  • 引用计数法
  • 可达性分析法

如何回收?

何时回收?

垃圾回收算法

  • 引用计数法
  • 复制算法
  • 标记清除
  • 标记整理
  • 标记清除压缩

垃圾回收器

  • CMS
  • Serial
  • G1

G1收集器通过多种技术实现了高性能和暂停时间目标。

堆被分区为一组大小相等的堆区域,每个区域都是一个连续的虚拟内存区域(region)。G1执行并发全局标记阶段以确定整个堆中对象的活跃度。在标记阶段完成之后,G1知道哪些区域基本上是空的。它首先收集在这些区域,这通常会产生大量的自由空间。这就是为什么这种垃圾收集方法称为Garbage-First。顾名思义,G1将其集合和压缩活动集中在堆的可能充满可回收对象的区域,即垃圾。G1使用暂停预测模型来满足用户定义的暂停时间目标,并根据指定的暂停时间目标选择要收集的区域数。

由G1确定为回收成熟的区域是使用疏散收集的垃圾。G1将对象从堆的一个或多个区域复制到堆上的单个区域,并且在此过程中压缩并释放内存。这种疏散在多处理器上并行执行,以减少暂停时间并提高吞吐量。因此,对于每次垃圾收集,G1会持续工作以减少碎片,在用户定义的暂停时间内工作。这超出了以前两种方法的能力。CMS(Concurrent Mark Sweep)垃圾收集不进行压缩。ParallelOld垃圾收集仅执行整堆压缩,这会导致相当长的暂停时间。

值得注意的是G1不是实时收集器。它以高概率但不是绝对确定性满足设定的暂停时间目标。基于先前集合的数据,G1估计可以在用户指定的目标时间内收集多少个区域。因此,收集器具有收集区域的成本的相当准确的模型,并且它使用该模型来确定在停留在暂停时间目标内时要收集哪些区域和多少区域。

  Oracle JDK 7 Update 4及更高版本完全支持Garbage-First(G1)垃圾收集器。G1收集器是一种服务器式垃圾收集器,适用于具有大容量存储器的多处理器机器。它以高概率满足垃圾收集(GC)暂停时间目标,同时实现高吞吐量。全堆操作(例如全局标记)与应用程序线程同时执行。这可以防止与堆或实时数据大小成比例的中断。

  • ParNew
  • ZGC

虚拟机工具:

  • 查看JVM信息:

    C:\Users\Administrator>jinfo -flags 10276
    Attaching to process ID 10276, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.131-b11
    Non-default VM flags: -XX:CICompilerCount=3 -XX:ConcGCThreads=1 -XX:G1HeapRegionSize=1048576 -XX:InitialHeapSize=268435456 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=643825664 -XX:MinHeapDeltaBytes=1048576 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation -XX:+UseStringDeduplication
    Command line: -Dosgi.requiredJavaVersion=1.8 -Dosgi.instance.area.default=@user.home/eclipse-workspace -XX:+UseG1GC -XX:+UseStringDeduplication -Dosgi.requiredJavaVersion=1.8 -Dosgi.dataAreaRequiresExplicitInit=true -Xms256m -Xmx1024m -javaagent:D:\eclipse\project\eclipse\lombok.jar

jps:java process status

jps -l 主类全名

jps  -m 运行传入主类的参数

jps -v 虚拟机参数

 

 

Class文件结构分析:

JVM体系结构及优化的更多相关文章

  1. JVM体系结构之一:总体介绍

    一.Java的内存区域划分 Java 虚拟机在执行Java程序的时候会把它管理的内存区域划为几部分,这一节我们就来解析一下Java的内存区域. Java的内存区域主要分为五部分: 程序计数器(PC) ...

  2. JVM体系结构详解

    每个Java开发人员都知道字节码将由JRE (Java运行时环境)执行.但是很多人不知道JRE是Java Virtual Machine(JVM)的实现,它分析字节码.解释代码并执行代码.作为开发者, ...

  3. jvm出现OutOfMemoryError时处理方法/jvm原理和优化参考

    The heap stores all of the objects created by your java program.The heap's contents is monitored by ...

  4. [转帖]JVM总结--JVM体系结构

    JVM总结--JVM体系结构 https://blog.csdn.net/samjustin1/article/details/52215274 需要不断的学习才可以. 2016年08月15日 22: ...

  5. JVM 体系结构与工作方式

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  6. 46张PPT讲述JVM体系结构、GC算法和调优

    本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.(内嵌iframe,建议使用电脑浏览) 好东西当然要分享,PPT已上传可供下载 ...

  7. JVM 体系结构概述 (一)

    一.jvm运行在操作系统之上的,它与硬件没有直接交互: 二.JVM体系结构概览 JVM的基本结构:类加载器.执行引擎.运行时数据区.本地方法接口: 过程:class文件 ----> 类加载器 - ...

  8. JVM体系结构之三:方法区之2(jdk1.6,jdk1.7,jdk1.8下的方法区变迁)

    方法区 方法区存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.HotSpot中也称为永久代(Permanent Generation),(存储的是除了Java应用程序创建的对象之 ...

  9. JVM反调调用优化,导致发生大量异常时log4j2线程阻塞

    背景 在使用log4j2打日志时,当发生大量异常时,造成大量线程block问题的问题. 一个关于log4j2的高并发问题:https://blog.fliaping.com/a-high-concur ...

随机推荐

  1. Python 基础语法_Python脚本文件结构

    目录 目录 前言 软件环境 Python Script文件结构 导入模块的流程 Python的包package 最后 前言 Python基础语法这一章,主要记录了Python的文件结构.逻辑运算符.算 ...

  2. 使用putty远程登录Ubuntu时,报Network error:Connection refused错误及解决(记录)

    putty远程登录Ubuntu,弹出Network error:Connection refused的错误提示框,就是因为Ubuuntu没有安装ssh服务.执行命令: sudo apt-get ins ...

  3. Nginx Server 上80,443端口。http,https共存

    server{ listen 80; listen 443 ssl; server_name www.iamle.com; index index.html index.htm index.php; ...

  4. 对于富文本编辑器中使用lazyload图片懒加载

    使用lazyload.js图片懒加载的作用是给用户一个好的浏览体验,同时对服务器减轻了压力,当用户浏览到该图片的时候再对图片进行加载,项目中使用lazyload的时候需要将图片加入data-orgin ...

  5. 用linux主机做网关搞源地址转换(snat)

    一.原理图  二.环境 外网  A:192.168.100.20 (vmnet1) 网关  B:192.168.100.10 (vmnet1)     192.168.200.10 (vmnet2) ...

  6. 【Qt开发】布局控件之间的间距设置

    void QLayout::setContentsMargins ( int left, int top, int right, int bottom ) Sets the left, top, ri ...

  7. lua基础学习(六)

    一.lua协同程序coroutine 1.什么是协同(coroutine)?Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共 ...

  8. linux环境下编译Android apk

    Android源码目录下的build/envsetup.sh文件,描述编译的命令 - m:       Makes from the top of the tree. - mm:      Build ...

  9. (转)使用JMeter对秒杀示例进行性能测试

    背景 秒杀是我们ServiceComb开源团队以领域驱动设计(DDD)为背景,从零开始构建一个微服务架构的示例项目:在<秒杀开发历程>系列博文中提到它作为一个高并发压力场景的应用,采用了C ...

  10. 【Linux 网络编程】常用套接字类型

    常用套接字类型<1>流式套接字(SOCK_STREAM)---TCP      提供面向连接的.可靠的传输服务,数据无差错,无重复的发送,      且按发送顺序接收.<2>数 ...