Java 虚拟机学习 不断积累

·Java虚拟机运行期的几个概念 

Java虚拟机运行期的几个概念,方法区:存储类,静态变量,其他一些运行时参数;堆:存对象和数组;方法区和堆是共享的。程序计数器:记录代码运行到那一行;虚拟机栈和本地方法栈分别服务于Java虚拟机的方法调用和本地系统的Native方法调用。
后面三个都是线程私有的。 

 

·Java 虚拟机内存分配方式分为指针碰撞和空闲列表

Java 虚拟机内存分配方式分为指针碰撞和空闲列表,前者在JVM内存区域中指针一边是已分配内存,另一边是未分配内存,这种情况需要内存压缩。空闲列表则需要维护一套内存空闲和使用表。

 

·JVM之Java类实例化的过程 

JVM之Java类实例化的过程,这里不讨论这个类是数组和class类的情况。首先JVM需要在方法区的常量池查找这个类对应的类符号引用,并且检查这个符号代表的类是否被加载,解析和初始化过,如果没有找到就需要加载这个类到方法区。第二,JVM在堆中根据类的相关信息为这个要创建的对象分配一定大小的内存(指针碰撞或者空闲列表策略),实际分配的时候采取CAS或者TLAB策略。第三,将分配的内存内容初始化为零值(不包括对象头;LTAB策略可以在分配内存的同时完成这个操作)。第四是为对象设置Object Header,,虚拟机实例化对象的工作就完成了,但是从语言层面来说,还需要执行init()方法,把对象按照程序员的意愿初始化。

 

·JVM之对象的内存布局

HotSpot虚拟机中,对象在内存中存储布局分为:对象头(Header)、实例数据(Instance Data)和对齐填充。其中对象头分为两部分,第一部分是定长的,在32位虚拟机中为32bit,在64位虚拟机中为64位,用于记录对象运行时的不同状态;第二部分是指向它的类元数据的指针,通过该类型指针可确定其属于哪个类,此外对于数组而言,需要再加第三部分来记录数组长度,强调下普通对象通过元数据信息即可确定大小。实例数据用以存储对象真正的信息,遵循一定的分配策略。至此对于对象头部和实例数据占用的空间合未必是8字节的整数倍,而HotSpot VM要求对象的起始地址必须是8字节的整数倍,即对象大小必须是8字节的整数倍,而对象大小是根据类元数据得到的,当这个大小不是8字节的整数倍就需对齐填充,填充这部分即对齐填充,当不需填充时就不存在了。所以对齐填充部分不是必然存在的。

·JVM之Java栈(虚拟机栈)调用堆中的对象的方式

 Java虚拟机栈(简称Java栈)描述的是Java方法执行的内存模型(内含局部变量表,也叫本地变量表),本地方法栈为调用Native方法服务,都是方法级别的。Java堆存储对象实例和数组。方法区存储类信息,常量,静态变量,即时编译器编译后的代码,运行时常量池存在于方法区。Java虚拟机栈访问对象的方式有两种,句柄和直接指针,句柄存储对象实例数据的指针和对象类数据的指针,直接指针存储的就是对象地址和对象类数据的指针,前者好处是reference指向确定,坏处是需要多一次操作,频繁操作会影响效率。Sun HotSpot是具体指针。

 

 

·JVM之内存溢出-堆、虚拟机栈和本地方法栈(Java栈)、方法区

Java虚拟机中,除了程序计数器外,其他内寸区域都有可能发生内存溢出,OutOfMemoryError(OOM)。VM Args:-Xms20m -XmX20m设置Java堆大小固定为 20M。-XX:+HeapDumpOnOutOfMemoryError在堆内存溢出时会Dump出当前内存转储快照,可以用Eclipse Memory Analyzer打开。-Xoss设置本地方法栈大小,-Xss设置Java栈大小。HotSpot不区分虚拟机栈和本地方法栈,故-Xoss参数无效。Java栈可能出现OOM和StackOverflowError(递归调用)。XX:PermSize和-XX:MaxPermSize限制方法区大小。在内存空间一定的前提下,线程数越多越可能导致栈内存溢出而不是StackOverflowError。原因是栈帧每分配一个就消耗一定的内存空间,线程越多分配越多,发生内存溢出的概率越大,单线程由于在已分配好的栈帧操作,出现StackOvetflowError的概率更大。栈帧大小是不固定的,默认配置下大小下,对于包括递归在内的正常方法调用,深度达到1000~2000是正常的。

 

·String.intern()和字符串常量池

这个细写了一篇博文 https://blog.csdn.net/bestcxx/article/details/88899648

 

·垃圾回收器
新生代
·Serial,jdk client模式默认新生代垃圾回收器 单线程,stop the world ,复制算法,最原始的新生代垃圾回收器
·ParNew, jdk server模式默认新生代垃圾回收器,多线程-多核效果好,stop the world,复制算法,jdk1.3 出现
·Parallel Scavenge, 新生代垃圾回收器,多线程,stop the world 关注吞吐量,复制算法,jdk1.4 出现

老年代
·CMS(Concurrent Mark Sweep),多线程,垃圾收集与用户线程(基本上)同时工作某线程部分阶段 stop the world,标记清楚算法,jdk1.5出现
·Serial Old,client模式默认老年代垃圾回收器,单线程,stop the world,标记整理算法
·Parallel Old,多线程,stop the world,标记整理算法,jdk1.6出现

垃圾回收器的匹配-从老年代垃圾回收器看
CMS:支持 Serial,ParNew
Serial old:支持 Serial、ParNew、Paraller Scavenge
Parallel Old:仅支持 Paraller Scavenge

 

[Jvm分区]

•Java Heap分为新生代和老年代。在Hotspot虚拟机中,新生代被划分为 一个Eden,和两个 Survivor(survivor from.和 survivorto),每次新生生成对象放到Eden,垃圾收集将存活的和Survivor from依旧存活对象复制到Survivor to中。

•Survivor from和Survivor to交替使用。

•一个Eden和一个Survivor内存大小比例是 8:1

•如果对象过大,大过新生代,会直接进入老年代。

 

·TP指标

TP指标: TP50:指在一个时间段内(如5分钟),统计该方法每次调用所消耗的时间,并将这些时间按从小到大的顺序进行排序,取第50%的那个值作为TP50 值;配置此监控指标对应的报警阀值后,需要保证在这个时间段内该方法所有调用的消耗时间至少有50%的值要小于此阀值,否则系统将会报警。

TP90,TP99,TP999与TP50值计算方式一致,它们分别代表着对方法的不同性能要求,TP50相对较低,TP90则比较高,TP99,TP999则对方法性能要求很高

 

 

 

你可能感兴趣的:(JVM)