JVM体系结构及优化
源文档: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体系结构及优化的更多相关文章
- JVM体系结构之一:总体介绍
一.Java的内存区域划分 Java 虚拟机在执行Java程序的时候会把它管理的内存区域划为几部分,这一节我们就来解析一下Java的内存区域. Java的内存区域主要分为五部分: 程序计数器(PC) ...
- JVM体系结构详解
每个Java开发人员都知道字节码将由JRE (Java运行时环境)执行.但是很多人不知道JRE是Java Virtual Machine(JVM)的实现,它分析字节码.解释代码并执行代码.作为开发者, ...
- jvm出现OutOfMemoryError时处理方法/jvm原理和优化参考
The heap stores all of the objects created by your java program.The heap's contents is monitored by ...
- [转帖]JVM总结--JVM体系结构
JVM总结--JVM体系结构 https://blog.csdn.net/samjustin1/article/details/52215274 需要不断的学习才可以. 2016年08月15日 22: ...
- JVM 体系结构与工作方式
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- 46张PPT讲述JVM体系结构、GC算法和调优
本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.(内嵌iframe,建议使用电脑浏览) 好东西当然要分享,PPT已上传可供下载 ...
- JVM 体系结构概述 (一)
一.jvm运行在操作系统之上的,它与硬件没有直接交互: 二.JVM体系结构概览 JVM的基本结构:类加载器.执行引擎.运行时数据区.本地方法接口: 过程:class文件 ----> 类加载器 - ...
- JVM体系结构之三:方法区之2(jdk1.6,jdk1.7,jdk1.8下的方法区变迁)
方法区 方法区存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.HotSpot中也称为永久代(Permanent Generation),(存储的是除了Java应用程序创建的对象之 ...
- JVM反调调用优化,导致发生大量异常时log4j2线程阻塞
背景 在使用log4j2打日志时,当发生大量异常时,造成大量线程block问题的问题. 一个关于log4j2的高并发问题:https://blog.fliaping.com/a-high-concur ...
随机推荐
- Linux下面配置安装jmeter(1)
一.下载安装JDK Jmeter依赖jdk环境,我们先准备jdk,查看是否安装jdk: # rpm -qa | grep jdk 或者 #Java –version 我本地已准备好了jdk ...
- fiddler抓取app的https的包
线上问题的排查有时候需要抓包,但是是https协议的,则需要安装证书 在Android 6.0 (API level 23)及以前,APP默认信任系统自带的CA证书以及用于导入的CA证书,Androi ...
- 系统分析与设计HW9
使用 ECB 实现 make reservation 用例的详细设计(包含用例简介,顺序图,类图) 用例简介: 搜索酒店 1.1 选择城市 1.2 选择日期 生成订单 2.1 选择酒店 2.2 选择日 ...
- C++统计程序运行时间代码片段
因为经常需要统计代码的运行时间,所以计时功能就显得很重要, 记录一下现在喜欢用的计时方式,供日后查阅. 1.下面是计时主函数, bool TimeStaticMine(int id,const cha ...
- 关于js函数闭包的理解
在开始之前我们先来了解一下函数的变量作用域 JavaScript 变量可以是局部变量或全局变量. 私有变量可以用到闭包. 全局变量 函数可以访问由函数内部定义的变量,如: 实例1 function m ...
- Java编程思想——标准 I / O
将Syetem.out转换成PrintWriter 标准I/O重定向: 控制台信息量大,滚动快,查看困难 setIn(InputStream) setOut(...) setErr(...) 新I/O ...
- 【VS开发】在VS2010中开发ActiveX控件设置测试容器的方式
在VS2010中开发ActiveX控件设置测试容器的方式 借鉴文章http://blog.csdn.net/waxgourd0/article/details/7374669 在VS2010中开发MF ...
- ios系统App Store安装包下载链接获取
今天将自己开发的Android版本和ios版本的安装包通过生成二维码的方式展示在H5页面上,Android版的比较简单,但是ios的安装包用户必须从App Store(苹果应用市场)中下载安装,所以获 ...
- Junit4 简单使用
一.环境搭建 对于习惯使用Eclipse开发平台来说,Junit早已是非常通常的插件,在Eclipse开发平台中,可以非常方便地搭建Junit测试环境. 1.在Eclipse上创建工程,任何Java工 ...
- lambda得用法