做java开发两年多了,一直没有深入研究过jvm运行原理,只是依稀的记得内存分为堆内存、栈内存,然后就是哪来着分为新生代和老生代,还有本地方法区,以前觉得这些东西面试用用也就算了,现在想来,不研究研究就不会有进步的,只顾复制粘贴不是出路,深入原理才是王道。
首先看到虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。
这个就是虚拟机的概念了,我原来的理解就是我的java代码 ->虚拟机->class文件->虚拟机->执行。但是不是这样的,虚拟机并不是生成class文件的而是一个运行环境,把class文件转换为特定系统的机器码。所以执行过程是java代码->编辑器(jdk)->class文件->虚拟机(jre)->特定系统机器码->执行。
虚拟机的工作主要分为以下3个步骤:装载、链接、初始化。
装载:把class文件读进虚拟机然后生成这个class的实例对象,大致过程就是类加载器找到class读到虚拟机当中,虚拟机读取class的类信息:类名、方法(名字、返回类型、参数列表)、变量、修饰符和常量池,一个类型的所有常量和符号引用都存放到方法区,然后生成实例对象存放在堆内存。
链接:验证语义、分配类变量内存、解析(在类型的常量池中寻找类,接口,字段和方法的符合引用把这些符号引用替换成直接引用的过程。)
初始化:初始化类的一些静态变量。
内存是分为四个区的:方法区、堆内存、栈内存和代码区。
类装载的时候:static块或常量等class的唯一标示会放在方法区当中。也就是说表明这个class是唯一的就是在方法区中保存的。还会产生一个空对象存放在堆内存,当new 一个对象出来的时候,其实就是在堆内存当中拷贝一个对象,当然还是存放到堆内存当中的,然后栈内存干啥的呢,其实栈内存是一个线程保持一个的,换句话说也就是一个人一个栈内存谁也别抢,堆内存相对就是共享的,栈内存存放基本数据类型和引用数据类型,引用数据就是直接指向了栈内存的类对象了。至于代码区,存放的是class二进制数据了吧。