JVM内核学习 --内存相关,内存结构, GC,ClassLoader,内存溢出

来源:互联网 发布:修改数据库字段长度 编辑:程序博客网 时间:2024/05/21 19:31

JVM启动流程


1.准备工作 1)jvm.cfg 2)JVM.dll

2.初始化


JVM的内部结构

PC寄存器:下一步指令

方法区:存放class对象(类的源信息),与永久区(Perm)关联在一起

        并不是绝对永久的,而是相对于应用中的对象

Java堆:应用中的对象,全局对象,线程共享

              GC主要是与Java堆的关系


把堆分代,分为新生代,老年代

把新生代分区,分为新生代,from,to  

都是为了GC的算法。


java栈:线程栈,每个线程都拥有一个java栈,是私有的,

     方法栈,帧栈,每个方法调用时创建一个帧,入帧,调用结束,出帧;

             帧:局部变量,操作数栈,常量池指针

    局部变量表:方法的参数,方法体中的局部变量

     操作数栈: a= 20; a+=30; //20,30就是操作数

     栈上分配,只有几百k-1M,其中的数据可被自动回收

             堆上分配,new出来的,需要GC,会有内存泄漏问题。


局部引用放在java栈,指向的对象放在java堆

            





GC垃圾回收

管理堆,永久区的内存,控制对象的生命周期

GC算法:

1.引用计数法

指向对象的引用的数量

问题:1.性能,引用和去引用伴随加,减法

           2.很难处理循环引用

虽然根节点不可达,但引用数量不为0,不可被GC回收


根节点可达:什么是根节点,线程栈中的引用都是根节点

2.标记-清除法

    根节点可达,标记,清除未标记

3.标记-压缩

  根节点不可达,标记,移动存活对象,清除边界。

  对比标记-清除法,多了一步移动的操作,造成不能与应用程序线程并发

4.复制算法

    不适合存活对象较多

    内存空间一分为二, 存活对象复制到另一块,清理使用的一块;

两块空间交替使用

   复制算法的优化:

    



   分代思想

新生代:短命 ,复制算法

老年代:长命, 标记清理或者标记压缩


 根节点可达性

 可触及性

 可复活 finalize()只可能调用一次

 根节点:线程栈

       方法区

        JNI

Stop-The-World,多半由GC引发

 举例:房间聚会,产生大量垃圾

    清理垃圾时,停止活动,聚会产生新的垃圾,不利于垃圾的标记和清理


GC参数

堆的结构

 eden:对象在新生代产生

tenured:大对象直接产生在老年代

eden,from,to 复制算法

垃圾回收器:

考虑减少停顿时间:1.并行,多线程处理加快GC速度

               2.并发,当应用程序线程运行时,并发运行GC,缺点是,GC线程减少了应用程序线程的吞吐量,

         应用程序线程的运行同时影响存活对象的标记。

1.串行收集器:SerialGC,效率高,但停顿时间较长

单线程回收

2.并行收集器:ParNewGC

 只作用于新生代


3.Parallel收集器,更加关注吞吐量

可设置新生代,老年代都是并行的


4.CMS收集器

   老年代采用并发标记-清除

并发,与应用程序线程一起进行

吞吐量:应用程序线程占用cpu





类加载

类加载过程

1.加载

把类的二进制流,转为 方法区 中的数据结构

在 java堆 中创建对应的java.lang.Class 对象 :xxx.class  

2.链接

1.验证 方法区中的东西

2.准备

分配内存,为类设置初始值(方法区)

3.解析

把符号引用转为直接引用

3.初始化 

执行 static变量,语句, clinit(构造方法,是线程安全的)

ClassLoader  负责类加载过程中的加载部分


双亲委托模式: 递归 如果找不到类的对象,向上层ClassLoader要求加载该对象,直到顶层,顶层ClassLoader如果不能加载该类对象,向底层要求加载该对象。

  层级关系

问题在于:加载一次类对象,可能要从底层到顶层,再从顶层到底层,

一种解决方法,在某层,如果找不到类的对象,先加载该对象,若加载不到,再向上层申请


RTTI(RunTime Type Identify)

类对象 与 对象:

对象是new出来的,

类对象是




内存溢出

堆溢出:对象过多
永久区溢出:类信息过多
栈溢出: 线程过多/循环调用
直接内存溢出

MAT memory analyzer
主要是分析堆内

支配树 

线程
入引用:谁有我的引用
出引用:我有谁的引用

浅堆:shallow Heap,一个对象占用的内存大小
深堆:Retained Heap,对象被GC回收后,可以回收的内存空间大小
         支配树上,一个对象及其支配对象的内存空间大小 


0 0
原创粉丝点击