JVM学习

来源:互联网 发布:毕业生找工作知乎 编辑:程序博客网 时间:2024/06/05 15:51
1.http://www.open-open.com/lib/view/open1408453806147.html
 open-jdk下载:http://download.java.net/openjdk/jdk7/
编译openJDK: http://blog.csdn.net/ge1mina023/article/details/48930855
 http://blog.csdn.net/ge1mina023/article/details/48930855



Java体系结构:
   a.java程序设计语言   b.各种硬件平台上的java虚拟机  c.Class文件   d.JavaApi 类库  e.第三方类库
JDK: java程序设计语言、Java虚拟机、JavaAPI
    堆内存和栈内存:栈内存实际上是指虚拟机栈(或者说是虚拟机栈中的局部变量表)
  jvm内存:方法区(线程共享区域)、虚拟机栈、本地方法栈、堆(线程共享区域)、程序计数器、运行时常量池(存放编译时生成的各种字面量和符号引用)
         方法区存放各个线程共享的内存区域,主要用于存储已被jvm加载的类信息、常量、静态常量等。
         String.intern()会因32和64的jvm而出现不同的现象。 
          垃圾回收机制(分代回收):新生代和老年代主要指Eden空间、From Survivor空间、To Survivor空间等
 2.NIO(new InputStream/OutputStream)基于通道(channel)和缓冲区(buffer)的I/O方式

3.对象在内存中存储的布局:对象头、实例数据和对齐填充 
4.hotspotVM的自动内存管理系统要求对象的起始地址必须是8字节的整数倍,即对象的大小是8字节的整数倍
5.reference类型在jvm中只规定一个指向对象的引用,没有规定如何访问对应的位置和方法,即由jvm实现而定。
   主流访问方式:句柄和指针两种。
   句柄:优点在引用处存储的是稳定的句柄地址,在对象被移动时(垃圾回收时移动对象是非常普通的行为)只改变句柄中的实例指针,不改变引用地址
   指针:速度更快,节省一次指针定位的时间开销



5.内存溢出:
   stackoverflow:线程请求的栈深度大于虚拟机所允许的最大深度       不断new对象
   outofmemoryerror:虚拟机在扩展栈无法申请到足够的空间。           不断启动新的线程就会出现

6.方法区和运行时常量溢出:
  String.intern()  //若字符串常量池里已经包含该字符串,则返回相应的字符串String对象;否则将此String对象加入常量池。
  list.add(String.valueOf(i).intern());   //会造成内存溢出

7.为什么jvm管理内存不使用引用计数算法来控制内存回收?
   因为很难解决对象之间相互循环引用的问题

8.可行性分析回收:以GCRoot作为起点,开始向下搜索(引用链),当一个对象到GCroot没有任何引用链相连,及证明对象不可用。


ClassLoader分为ExtClassLoader:用于加载Java扩展的API(/lib/ext中的类)    和 AppClassLoader用于加载ClassPath设置目录中的Class.
   特点:
           a.ClassLoader具有层次关系,loadClass()是入口。             b.Class.forName()能动态加载一个类
          c.不同的类加载器分别创建的同一个类的字节码数据属于不同的对象,没有关联。
 2.JVM:进程级别的实例
       a.产生:当启动一个JAVA程序时,一个JVM实例就会产生,任何一个public static void main(String args[])的class都可以作为JVM运行的起点。
       b.运行:main()作为该程序初始线程的起点,该应用中的其他线程都由该线程启动。
               1.非守护线程:如main() 
               2.守护线程:由jvm自己使用,程序可以指定线程为守护线程
       c.消亡:程序中所有守护线程都终止时,jvm才能退出,也可以通过Runtime类或者System.exit()来退出(安全管理器允许才行)
3.JVM体系结构
       a.类加载器(classLoader) 装载 .class文件
       b.执行引擎(执行字节码或者本地方法)
       c.运行时数据区(方法区、堆、java栈、PC寄存器、本地方法栈)

4.JVM类加载器:

       a.通过类名+包名+ClassLoader实例ID找到对应的二进制字节码并加载JVM中

       b.链接:1.负责对二进制字节码的格式进行校验、初始化装载类中的静态变量以及解析类中调用接口、类。

                     2.完成校验之后,初始化类中的静态变量并赋初值。

                     3.最后对类中的属性、方法等进行验证,以确保其需要的属性、方法和对应的权限存在,可能

                        报NoSuchMethodErrorNoSuchFieldError等错误信息。

5.初始化:

      a.执行类中的静态初始化代码、构造器代码以及静态属性的初始化。

          四种情况下会执行:

                  a.调用了new                   b.反射调用了类中的方法

                  c.子类调用了初始化       d.JVM启动过程中的初始化类

 6.JVM类加载顺序:

      a.两种类加载器:启动类装载器(JVM实现的一部分)和用户自定义类加载器(Java程序的一部分,必须是ClassLoader类的子类)

 7.JVM装载顺序:

      a.JVM启动时,由BootStrap向User-Defined方向加载类;

          应用进行ClassLoader时,由User-Defined向BootStrap方向查找并加载类。

      1.Bootstrap ClassLoader(JVM的根ClassLoader),JVM启动时初始化此ClassLoader,并由此ClassLoader完成jre/lib/rt.jar(sun JDK实现)

         中所有class文件的加载。   注:rt.jar包含java规范定义的所有接口以及实现

      2.Extension ClassLoader   JVM用于加载扩展功能的一些jar包

      3.System ClassLoader   JVM用来加载启动参数指定的Classpath中的jar包以及目录,如AppClassLoader

      4.User-Defined ClassLoader  

               继承ClassLoader自定义ClassLoader类,用于加载非Classpath中的jar包以及目录

8.JVM常用几个方法:

       a.loadClass:  加载指定名字的类,先从已加载的类中寻找,没有则继续从parent ClassLoader中寻找,仍没找到则从System ClassLoader中寻找,

          最后调用findClass方法查找;   如要改变类的加载顺序,可覆盖此方法实现。

       b.findLoadedClass:  从ClassLoader实例对象的缓存中寻找已加载的类,调用native方法。

       c.findClass:   直接抛出ClassNotFoundException,可以通过覆盖此方法和loadClass来加载相应的类。

       d.findSystemClass  从System ClassLoader中寻找类,未找到,则继续从BootStrap ClassLoader寻找,没有就返回null.

       e.defineClass  将二进制的字节码转换为Class对象

       f.resolveClass  负责完成Class对象的链接,如已链接过,则直接返回。

9.JVM执行引擎

       a.invokestatic:调用类的static方法

       b.invokevirtual:调用对象实例的方法

       c.invokeinterface:将属性定义为接口来调用

       d.invokespecial: 当JVM对于初始化对象(Java构造器的方法为:<init>)以及调用对象实例中的私有方法时调用

   JVM主要的执行技术有:

        1.解释    第一代JVM

        2.即时编译  第二代JVM

        3.自适应优化 如目前的HotspotJVM  开始对所有的代码都采取解释执行的方式,并监视代码的执行情况,

                对那些经常调用的方法启动一个后台线程,将其编译优化为本地代码;如该方法不再频繁使用,则

                取消编译过的代码,仍对其解释执行。

        4.芯片级直接执行

10.JVM运行时数据区:

        1.PC寄存区:存储每个线程下一步将执行的指令,如该方法被native修饰,则PC寄存器不存储任何信息。

        2.JVM栈 :  JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈存放的为当前线程的基本类型

            变量(八种数据类型:booleancharbyteshortintlongfloatdouble)、部分返回的结果以及

            Stack Frame; 非基本类型的对象在JVM栈上仅存放一个指向堆的地址。

          学习链接:http://www.open-open.com/lib/view/open1408453806147.html

0 0