关于jvm的一些认识-----------第一阶段

关于指令重排

jvm在编译的时候可能会使代码重新排下序。当然也有一定的限制。

关于jvm中的内存

据说常量池在jdk7之后,从方法区,移到了堆内存中。

栈中的调用堆中的,堆中的调用方法区的。

栈是帧栈,每次方法进去,压入一帧来处理,方法处理完毕,就出栈。在栈中有局部变量表,这个还有一点没有搞清楚。局部变量表会存着参数的信息

栈,pc寄存器是线程私有的。每创建一个线程,便会创建一个栈和一个pc寄存器。因此不要设置栈内存过大,否则每有一个线程就会创建一个栈。内存损耗的就会很大的。

为嘛会要加锁在多个线程调用同一个资源的时候。因为堆是堆,每个线程在工作内存中执行,即(栈中),只是读和写两个单独的操作不会被打断。读和写之间还是有可能被打断的。

关于类加载(取得二进制流,加载到方法区,在堆中新建一个对象)

加载---》链接----》初始化。其中链接又会分好多步啊啊啊啊。其中,链接又分好多步。验证(语法上的错误)--》准备(分配内存)--》解析(符号引用转化为直接引用,且初始化变量)

关于类加载啊啊啊,还是比较复杂的

jvm中有三个类加载器,分别是bootstrap类加载器和extension类加载器和application类加载器。其中呢,不同的类加载器加载不同路径下的类。

比如bootstrap加载的是rt.jar(核心类)。extension加载的是下面的类,而application加载的是classpath路径下的。

类加载器采用的是双亲委托模式。其中呢,从最低层,往上查找是否加载了类,如果没加载则一直往上,知道bootstrap类加载器。然后一直往下用类加载器加载。

当然我们也可以自定义类来破坏这种机制。

被不同的类加载器加载的即使是同一个类,但是他产生的对象还是属于不同的类的,因此之间不可以进行相互转化,或者相互转化为false;因此这里可以利用版本更新中

在类加载机制这里啊,我们还存在一个问题,这里,只要看炼数成金的ppt就可以知道了,这个问题留着以后来解决

用ASM操作java字节码,操作类

关于垃圾回收

关于finalize方法

其中可达对象,经过赋值null后,会变成可复活对象,此时的对象保存在一个list中。当对象调用finalize方法时,如果没有使对象获得引用,那么此对象就会被回收。

其实,就相当于我们小时候玩的合金弹头啦。一开始,我们都在游戏中各种浪,一不小心死了,变成可可复活对象,然后只有充游戏币,才能够继续。但是finalize方法只能调用一次,说明我们只能充一次游戏币。挺傲娇的游戏机哈。

分代回收垃圾

回收垃圾的算法有标记清除(直接标记出可达对象,不可达对象直接清除),标记压缩(直接标记出可达对象,压缩可达对象到一处,可能减少碎片化。挺适合老年代的。因为既然能升级到老年代说明程序用到他的地方还是挺多的,会一直用下去,因此要排列整齐。清理的对象也不是很多,压缩的对象应该也不是很多。当然也要留出空间来给大的对象,否则的话大的对象分配不进去),复制(分为两个区,将可达对象复制到另一个区中,直接清除原先的区。适合新生代,因为要清理的垃圾很多,然后只要复制一点点,就可以完成垃圾回收)

回收垃圾的集中回收器

Serial收集器(串行搜集器)

采用了复制算法,回收新生代垃圾,采用标记压缩算法回收老年代。这个是串行的,所以速度会比较慢,但据说听靠谱的

ParNew收集器

新生代采用了并行的回收器

关于parallel回收器,和parnew很像。只不过,老年代回收的话,也可以改成并行的。并且考虑了系统的吞吐量。关于系统的吞吐量还不知道是啥。等下去了解吧

 关于cms垃圾回收器

回收的是老年代的垃圾,主要用标记清除。因为用标记压缩的话,程序还在运行呢,怎么可能能动对象

CMS的GC过程有6个阶段(4个并发,2个暂停其它应用程序):
初次标记:为手机应用程序对象暂停其它应用。
并发标记:从初次标记收集到的‘根’对象引用开始,遍历所有能被引用的对象。
并发预清理:改变当运行第二阶段时,由应用程序线程产生的对象引用,以更新第二阶段的结果。
重新标记:由于并发预处理是并发的,对象引用可能发生进一步变化。因此,应用程序线程会再一次被暂停以更新这些变化,并且在进行实际的清 理之前确保一个正确的对象引用视图。这一阶段十分重要,因为必须避免收集到仍被引用的对象。
并发清理:所有不再被应用的对象将从堆里清除掉。
并发重置:收集器做一些收尾的工作,以便下一次GC周期能有一个干净的状态。

和serial搜集器相比,唯一有改变的地方是新生代采用了并行回收,对于单cpu来说,反而会使速度降低,因为线程还要开销

我所认识的jvm把堆内存分为了新生代(eden和from区和to区)和老年代区。

其中垃圾回还会回收持久代区。其中持久代区是回收方法区(类的信息加载到这里面)中的垃圾

其中根搜索算法他的根是

栈中引用的对象。类中引用的静态变量和常量。本地方法栈引用的对象。

想想就知道这个还是很不错的。

还有一个深堆和浅堆和支配树的概念。

浅堆是自己的结构所占有的内存,深堆是自己的结构,包括以自己为节点的支配树下的所有的内存结构

关于Full GC的概念

 老年代垃圾或者永久代垃圾满了,就会调用一次Full GC。他耗费的时间就会比较久咯

关于锁

偏向锁,轻量级锁和无锁,常规锁

减少锁的粒度

有时候还会增加锁的粒度呢,因为有些几乎可以不计,反而获取锁的,保持同步的会更耗性能一点

关于对象,每个对象都有一个对象头,对象头占了8个字节,都是一些关于锁的信息和分代年龄的信息,一般当年龄超过十五岁,便进入老年代区

关于类的字节码啥的还是比较麻烦的,在此不做叙述了,我也没搞得太懂

猜你喜欢

转载自www.cnblogs.com/czk666/p/9339625.html