一、用记事本写出一个java程序HelloWorld
第一步:写java源代码程序:HelloWorld.java
第二步:编译java源代码程序,生成helloWorld.class文件,字节码文件
第三步:运行程序(在jvm里运行)
二、JVM概念
1.JVM是JRE的一部分,它是一个虚构出来的计算机,是通过在实际的计算机上仿真各种计算机功能来实现。JVM有自己完善的硬件架构,如处理器、堆㡯、寄存器等,还具有相应的指令系统
2.Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。所有JAVA虚拟机JVM是属于JRE,而现在我们安装JDK时,也附带安装了JRE,JRE又包含了JVM
3.JAVA底层的指令不是我们关系的内容,我们需要关注java程序在jvm中运行时需要的内存,内存是由JVM自动管理的,由于程序或者硬件的原因会出现内存泄漏或溢出,到处程序崩溃,所以我们需要了解JVM内存结构
4.JVM内存图
5.JVM分为:1.类加载器子系统 2.运行时数据区(核心关注堆、栈、方法区)3.执行引擎
三、JVM核心内容分析
1.虚拟机栈:存放方法里的参数,局部变量,以及变量里的数据
1.1 是和线程紧密联系的,每创建一个线程就对应创建一个Java栈,所以java㡯也是“线程私有”的内容区域,这个栈又包含多个 栈帧,每调用一个方法时,就往栈压入一个栈帧,栈帧是用来存储方法数据和部件过程结果的数据结构,每个方法从调用到 最终返回结果的过程,就对应一个栈帧从入栈道出栈的过程
1.2 虚拟机栈是一个后入先出的数据结构,线程运行过程中,只有一个栈帧是处于活跃的,称为“当前活动帧栈”,当前活动帧 栈始终是虚拟机栈的栈顶元素
2.方法区:存储类结构信息,包括常量池、静态变量、构造函数等类型信息,类型信息是由类加载器在类加载时,从类文件中提取出来的:所以不要创建太多的静态变量,不被常用的,少创建
2.1 方法区同样存在垃圾收集,因为用户通过自定义加载器加载一些类称为垃圾,JVM会回收一个未被引用类所占的空间,以 便方法区的空间达到最小(垃圾回收重点关注堆垃圾回收)
2.2 方法区还存在常亮池,常量池包含一些变量和符号引用(基本数据类型的值(1,2,3,4,5),字符串)
2.3 线程共享的
3.程序计数器:是一个数据结构,用来保存当前程序的内存地址。方便线程切换能恢复到正确的位置。
4.本地方法栈:跟虚拟机栈很像,为了虚拟机使用Native方法服务的。
5.堆:存储java实例或者对象(所有被new出来的),是GC的主要区域。也是线程共享。
分析:
1.执行main方法,先为这个主线程创建一个栈区,再为main方法,创建一个栈,存放临时变量i1、i2、a、b
2.i1和i2的引入,分别是Integer对象,所以在堆中,创建了I1和I2,2个对象,栈的i1、i2存放了对象的地址
3.a和b的引用是1,放在方法区的常量池里,因为a在常量池创建了1,使用b的时候,先看常量池有没有1,没有才会继续创建,所有常量池中只有一个1,这也是常量池复用的一个特点,所有i1==12为false,a==b为true
总结:
4. 堆内存内部结构
1.所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制
2.堆被分为新生代和老年代,新生代又被划分为Eden(伊甸园)和Survivor(幸存者),老年代后面补上堆区,是永恒代(方法区)
3.结构示意图
解析:
1.新new的对象会放在eden,直至占满eden,会触发minor gc,会扫描eden、so、s1,如果是垃圾会被标记unreferenced,可达对象会被标记referenced,可达对象,会被放在其中一个survivor区域,另一个survivor区域和eden区域就会被清除,就这样循环反复
2.可达对象还有次数这个标记,代表幸存的次数,当幸存对象的年龄到达一个值后,就会从年轻代进入老年代
3.eden和survivor的比例为8:1,年轻代的对象基本上是80%以上被清理,老年代比年轻代内存大,如果老年代内存满了,就会触发major GC或者full GC。触发full GC就会出现所谓的STW(stop theworld),所有进程挂起,等待清理垃圾。
4.major GC是回收老年代的垃圾,Full GC 是回收老年代和年轻代的垃圾
5.JVM的垃圾回收器判定是否是垃圾数据的一般方法:
许多java的垃圾收集器都使用引用的根集GC roots,作为判断对象存活与否。引用的根集是正在执行的java程序随时都可访问引用的变量的集合--也就是存在对栈或者静态存储空间上的引用变量。从这些根集变量出发,可直接或者间接到达的对象,垃圾收集器胡人为是生命尚存的对象;相对从这些根集变量触发通过任何途径都无法达到的对象,就是死亡的,下次被清理的
6.永久代:存放的是java中的类,及加载类的类加载器本身。