认识jvm

1.jvm是什么

    java语言之所以能跨平台运行就得意于虚拟机,jvm是虚拟的计算机运行在操作系统之上,我们编写的java文件就是通过虚拟机进行编译成二进制的class文件,运行在jvm上面,所以用java所写的程序可以实现一次编译到处运行。其实是虚拟机屏蔽了不同的系统,提供了统一的接口而已。。。

2.jvm内部构成

   

   程序计数器:每个线程都会有一个程序计数器,记录当前线程下一步要执行的指令,就是你的程序当前执行到哪里,下面将要执行啥,比如分支,循环,跳转,异常处理,线程恢复都依赖它。

   虚拟机栈:主要存放局部变量表,动态链接,操作数栈,方法返回值,方法地址等等。

   堆:堆主要用于存放程序中的对象,应该说面向我们开发人员

   非堆:方法区是面向虚拟机的,主要存放一些编译后的class,类的meta,常量,静态变量 

   说到这里我想到一点Java内存模型与Jvm内存区域的一个比较,java内存模型你就可以理解为它是面向硬件的,是对硬件的一种抽象或者说一种映射,也就是说不同的操做系统对硬件内存都有自己的一套分配管理机制,java就是通过虚拟机间接的跟操作系统交互,从而完成内存管理;而jvm内存区域应该说是功能上的划分,是程序运行时把数据划分成这几个模块方便区分使用而已,这是从两个不同的层面划分的,没啥关系。

    参考:http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html

3.jvm工作原理

   由于没有对虚拟机内部原理有过多深究,所以不敢多说,网上参考资料有很多,这里推荐一个个人认为写的不错的博文,初学时可以看看,了解下http://blog.csdn.net/ning109314/article/details/10411495

4.jvm特点

   可以说jvm最牛逼的地方就是gc了,像之前写过c/c++的学都知道,每次都需要自己手动的分配内存,自己去释放内存,这就对程序员的水平要求比较高,万一不小心哪里一下忘掉了去释放内存可能带来很严重的后果,比如说内存泄露甚至系统崩溃,这里说下内存泄露与溢出的区别,(我就想到哪里说到哪里,当然大方向是确定的,各位读者不要介意哦,因为我发现,我们在看其他博文时,经常会有很多不知道的名词或概念不知道还得去查,这里我能多说一句的就给大家说了,省得再去查麻烦 )。

    内存泄露:是指程序运行时分配的空间,运行结束后内存空间无法得到释放,导致这一块内存无法被回收使用,这样一来如果不及时解决内存早晚被占用完而出现的内存泄露,这是程序问题,比较严重。

    内存溢出:是指你申请的空间不够,满了,就好比杯中的水往外溢出这样。

    好,说完我们继续来说gc,有了gc我们就不需要再去手动的分配释放内存了,虚拟机在后台开启一个线程会在适当的时候对我们程序运行后没用的对象进行回收,当然gc只回收堆内存中的无用对象,这样就大大提高了编程效率保护了编程的完整性,同时也带来另一个问题,那就是系统的开销增加了,你想啊,gc是不是也需要占内存占资源的而且需要对大量的对象进行跟踪势必少不了占用大量资源,所以说Java语言慢就是这儿的原因,不过只是相对的,随着硬件的发展,软件的优化,java速度方面一点都不逊色。。。

    以上是对gc的一个大概的介绍,下面给大家列出几条gc的几个特点,方便面试时直接说

    1.1 gc只回收堆中无用对象;

    1.2 gc具有不可预知性,程序无法精准控制垃圾回收机制的执行;

    1.3 可以将对象引用设置null暗示其回收;

    1.4 垃圾回收机制回收对象,总会先调用finalize方法(如果覆盖该方法,让一个新的引用重新引用该对象,则会重新激活对象);

    1.5 程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定

    1.6 永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用

    垃圾回收机制中的算法

    2.1 标记清除

           从根开始将可能被引用的对象用递归的方式进行标记,然后将没有标记到的对象作为垃圾进行回收。

           基础算法,会产生大量碎片,不利于为其他大对象分配连续可用空间。。。

     2.2 复制收集

          把内存空间划分为2个相等的区域,每次只使用一个区域。垃圾回收时,遍历当前使用区域,把正在使用的对象复制到另外一个区域。不会产生碎片,复制时应用暂停,浪费空间。

     2.3 标记清扫
    原理:对于“活”的对象,一定可以追溯到其存活在堆栈、静态存储区之中的引用。这个引用链条可能会穿过数个对象层次,算法基于有向图,采用深度优先搜索。
    第一阶段:从GC roots开始遍历所有的引用,对有活的对象进行标记。
    第二阶段:对堆进行遍历,把未标记的对象进行清除。
优点:解决了循环引用的问题。
    缺点:
(1)暂停整个应用;
(2)会产生内存碎片。
(3)不管你这个对象是不是可达的,即是不是垃圾,都要在清楚阶段被检查一遍,非常耗时.

sun前期版本就是用这个技术。

     2.4 标记压缩
    第一阶段:同标记-清扫,标记活的对象,
    第二阶段:这个阶段将所有做了标记的活动对象整理到堆的底部
    优点:
(1)避免标记扫描的碎片问题;

(2)避免停止复制的空间问题。

     2.5 分代收集

           原理:基于对象生命周期分析得出的垃圾回收算法。把对象分为年轻代、年老代、持久代,对不同的生命周期使用不同的算法(2-3方法中的一个即4自适应)进行回收。

J2SE1.2以后使用此算法  

JVM分别对新生代和旧生代采用不同的垃圾回收机制

      导致Gc的情况:
         1、tenured被写满
         2、perm被写满
         3、System.gc()的显式调用。
         4、上一次GC之后heap的各域分配策略动态变化。


    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值