jvm--从java类的编译到垃圾回收

1.javac编译的四个阶段

词法分析,语法分析,语义分析到字节码的生成。

--将.java转化成.class的字节码文件

2.类加载过程

加载->链接(验证+准备+解析)->初始化(使用前的准备)->使用->卸载 

将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的java.lang.Class对象,用来封装类在方法区类的对象。

3.堆分区

新生代、老年代、永久代  --经过多少次GC回收后的新生代会进入老年代

4.jvm内存模型

栈区: 

    java虚拟机栈:线程私有的,生命周期与线程相同,存放局部变量表,操作栈,动态链接,方法出口

    本地方法栈:为虚拟机使用到本地方法服务(native)

堆区:被所有线程共享区域,在虚拟机启动时创建,唯一目的存放对象实例 (GC主要光顾区域)

方法区:所有线程共享区域,用于存放已被虚拟机加载的类信息,常量,静态变量等数据(永久代)

程序计数器:当前线程所执行的行号指示器,比如循环,分支,跳转,异常处理,线程恢复等

5.GC垃圾回收

GC触发条件:

    可达性分析法:这个算法的基本思想是通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的。

垃圾回收主要针对Java堆内存中的新生代和老年代,针对新生代,主要采用复制算法,而针对老年代,通常采用标记-清除算法或者标记-整理算法来进行回收。

复制算法:将内存分成大小相等的两块区域,每次使用其中的一块。当这一块的内存用完了,就将还存活的对象复制到另一块区域上,然后对该块进行内存回收。

标记-清除算法:在标记阶段将标记出需要回收的对象空间,然后在下一个阶段清除阶段里面,将这些标记出来的对象空间回收掉。这种算法有两个主要问题:一个是标记和清除的效率不高,另一个问题是在清理之后会产生大量不连续的内存碎片,这样会导致在分配大对象时候无法找到足够的连续内存而触发另一次垃圾收集动作。

标记-整理算法:在标记需要回收的对象以后,它会将所有存活的对象空间挪到一起,然后再执行清理。标记-整理(Mark-Compact)算法有效预防了标记-清除算法中可能产生过多内存碎片的问题。

 

垃圾收集器:

    新生代收集器:主要有Serial收集器、ParNew收集器和Parallel Scavenge收集器。

    老年代收集器:主要有Serial Old收集器、Parallel Old收集器和CMS收集器

 

 

 

 

 

阅读更多

JAVA 垃圾回收

06-28

请看下面的程序运行的结果,rnrn为什么垃圾回收器会连续回收两个最近的对象(4731hello2,4730hello2)rnrn然后再从最前面回收(hello1)然后又回收两个最近的对象(4729hello2,4728hello2)rnrn然后回收当前最前面的对象(1hello2)rn而以后的规律却变成了rnrn1.回收当前最近的对象(4727hello2)rnrn2.回收当前最久的对象(3hello2)rnrn3.重复执行上面1、2两个步骤。rnrnrn我的系统是winxp jdk 用的是 1.6.0-beta2rnrn为了能看到了这么多行结果我在Eclipse 中运行了这个程序rnrnrn是不是所有的垃圾回收都是按这个规律回收的呀,rn还是跟本就没有什么规律rn我想知道它的工作过程rnrnrnrnpublic class test rn static long time=1;rn public test() rn rn public static void main(String[] args) throws Exception rn System.gc();rn hello1 h1=new hello1();rn h1=null; rn for(long t=0;t<10000;t++) rn rn System.out.println(t); rn rn hello2 tt=new hello2(); rn rn if(t<4744) time=1;//经过多次实验,我的机子会在这附近进行垃圾回收rn else time=500;rn Thread.sleep(time); rn rn rn rnrnclass hello1rn static long count;rn long con=0;rn hello1()rn count++;rn con=count;rn rn protected void finalize()rn System.out.println("回收第"+con+"hello1");rn rnrnclass hello2rn static long count;rn long con=0;rn hello2()rn count++;rn con=count; rn rn protected void finalize()rn System.out.println("回收第"+con+"Hello2");rn rnrnrnrn某一次程序执行后显示的代码:rnrn1rnrn2rnrn......rnrn4730rnrn4731rn回收第4731Hello2rn回收第4730Hello2rn回收第1hello1rn回收第4729Hello2rn回收第4728Hello2rn回收第1Hello2rn回收第4727Hello2rn回收第2Hello2rn回收第4726Hello2rn回收第3Hello2rnrn......rn

没有更多推荐了,返回首页