失效链接处理 |
jvm性能调优文档 PDF 下载
本站整理下载:
相关截图:
![]()
主要内容:
间是线程独有的空间,每个线程都会拥有一份虚拟机栈空间,这个很重要。知道栈帧的概念,每个方法加载到虚拟机栈中都以一个栈帧的形式存在,栈帧中存放着方法的形参,局部变量,动态链接,方法出口等。百度百科的解析是:C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。从逻辑上讲,栈帧就是一个函数执行的环境:函数参数、函数的局部变量、函数执行完后返回到哪里等等。当某方法被某线程执行的时候,线程所属的虚拟机栈中会生成该方法的栈帧,所以栈帧都是归属于各自的线程的,栈帧的内容只有该线程能读取,所以多个线程执行同一个方法的时候,方法都能在各自线程中独立执行,互不干扰。
②本地方法栈:存放native方法的栈帧,与底层硬件方法接触,不需要深究。
③堆:存放实例化的对象。
④方法区(又叫永久区Permanent Generation):防止类信息,静态便令,常量等。
3.堆内存
其实常说的虚拟机优化主要是堆内存区的优化。它是虚拟机内存中最大的一块区域。
1)堆内存结构
2)解释:
宏观来讲可以分成new区和old区,也称为新生代区和老年代区。
新生代又分成三块,一块eden(伊甸园)区,两块survivor(幸存者)区,两块survivor大小是一样的。老年代只有一块,叫tenured(老教授)区。
对象被放到堆内存中各块的逻辑:一个对象被new出来后,如果特别大的对象,直接放到tenured区,否则都被放置在eden区,所以eden区就是放置新生对象的区域。经过一次GC(垃圾收集)后,eden区中的对象依然有引用指向(也就是说有变量指向它),则这些对象会转移到survivor区,其他对象被回收,转移到survivor区的过程看“copy(拷贝)算法”。当经历了n次GC后,对象依然没被回收,会放到tenured区去。如果对象拷贝到survivor中发现装不下了,也会直接放置到tenured区中。
各区的空间比例:如果new区分成10份,那么eden区占8份,survivor区分别占1份。而new区对old区的比例往往是1:3,1:2,3:8等等。eden区设置比较大因为初生的所有小对象都会放到eden区,而survivor设置比较小因为经过GC后,剩下的对象往往已经很少了,而且surviver设置比较大的话,会浪费内存。老年代设置比较大原因是他存放的是大对象,并且程序中所有多次GC未被回收的对象都会放到这个区中。
4.什么是垃圾
我们一般认为没有引用指向的对象,虚拟机认为是可回收的垃圾,比如String s = new String(“aaa”),对象s放在栈中,当我将null赋值s,那么s引用就不在指向该对象了,那么该对象就是垃圾。另外一种情况是,如果两个对象内部有引用相互指向,形成一种死锁结构,那么这两个对象也称为垃圾,引申开来,如果一堆对象内部形成一个闭环的引用,那么这些对象都看作是垃圾。
对于如何确定垃圾,需要弄明白强、软、弱、虚引用的概念,参考https://www.cnblogs.com/yw-ah/p/5830458.html。
其中有两种算法用于判断对象是否为垃圾:
①引用计数:
意思是记录某个对象有多少个引用指向,只要不等于0,则表示有它不是垃圾,但是这种算法有问题,就是上面说的循环引用或者闭环引用,这种算法无法识别。
②正向可达:
意思是,虚拟机中有一个GC root节点,你可以认为这是一个逻辑节点,所有的初始引用都在这个节点上,那么每个引用指向一个对象,那么这个对象肯定不是垃圾,如果这个对象里面又有一个引用指向另一个对象,那么被指向的对象也不是垃圾,依次类推,顺着藤摸瓜,除了这些正向可达的对象,其他对象都是垃圾,而且正向可达是可以区分循环引用和环形引用垃圾的。
5.垃圾收集算法
①mark sweep(标记清除)算法
1.概述
jvm调优一般出现在部署或者架构工程师对java虚拟机的调优,让其性能达到最好。
原则:无监控不调优。意思是你调优之前必须有确切的性能论证,因为调优的过程必须进行测试验证,如果没有性能结果对比,调优是没有意义的。
2.java内存结构
①虚拟机栈:虚拟机栈空
意思是,图片右上方网格中,黑色的块表示虚拟机识别出来的可回收垃圾对象,标记清除算法就是为这些黑色的块做一个记号,GC的时候,找到有记号的内存块,将其内容清除,最终变成右下方的网格。
优点:刚开始的时候,效率非常高,不需要做内存间的拷贝。
缺点:清除后的内存呈零散状态的可用空间,而大对象需要连续的内存空间,如果一个大对象在这些零散的标记清除过后的内存中找不到地方存放,虚拟机会进行一次full gc,将内存区域压缩,也就是将零散的内存块排整齐后再存放该大对象,这样效率反而会低。
②copy(拷贝)算法
意思是,看右上方的网格,它将内存分成上下两个等大小的空间,最开始的时候使用上层网格空间,灰色格子表示对象,当GC发生后,上层的灰色格子拷贝到下层的完全未使用的内存空间中,同时,灰色格子被压缩排列整齐,然后上层网格所有内存被清理,变成绿色可用空间,此时新进来的对象就放到下层的绿色网格空间中,完成一次GC过程,如果再一次GC,同理,下层的灰色对象会全部拷贝到上层,排列整齐,清空下层空间,新来的对象存放在上层…以此类推。这就是survivor区默认算法,从a层到b层拷贝,那a层会被称为from space,b层会被称为to space,上下两层轮流作为from space和to space。
优点:解决标记清除算法的内存碎片化的问题。效率很高,不管是拷贝,还是清除整块空间的内存,速度都是非常快的。而且顺带的进行了内存的压缩。
缺点:浪费内存,因为它的机制是来回拷贝,所以同一时间永远只有一半的内存得到使用。
③mark compack(标记压缩)算法
|