JVM细节

来源:互联网 发布:直播吧软件下载 编辑:程序博客网 时间:2024/06/05 15:11

JVM内存:





1.heap

内存是无序的。存放对象,当内存空间不够时报错信息为OutOfMemoryError

垃圾回收:可达性分析


      在Java中,可以作为GC Roots的对象有以下几种:

  • 虚拟机栈中的本地变量表中引用的对象,也就是正在执行函数体中的局部变量引用的对象。
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中(Native方法中)引用的对象  

判定对象可以回收:

1.把引用赋值为null,或者把引用指向新对象

2.局部变量执行完,生成的对象都可以被回收

3.弱引用与其关联

判对象死刑,2次标记:

http://www.cnblogs.com/duke2016/p/6013519.html

第一次标记就是筛选

第一次标记时会进行一次筛选:筛选的条件是是否有必要执行finalize()方法。
当对象没有覆盖finalize()方法,或者finalize()被虚拟机调用过,则虚拟机认为没有必要执行finalize()方法

 如果这个对象有必要执行finalize(),则会放在一个队列里,以一个低优先级的线程进行执行finalize()方法进行二次标记,如果在finalize()方法中,对象重新回到引用链上(比如this赋值给其他引用链上的对象),则该对象不被回收,而移出该队列。
    注意:finalize()方法只被调用一次,如果这个对象在GC时被调用过一次finalize()方法,则第二次GC的时候,就会被判断为没有必要执行finalize()而被直接回收。

典型的垃圾回收算法:代码我以后看到了会补上

1.先标记再清除,缺点是内存碎片太多


2.复制算法:把内存分为完全相等的2块,每次只使用其中一块。当这个用完,把还活着的对象复制到另一块,这一块就全部清空。

                    优点:解决了内存碎片                 缺点:以前还能用一整块,现在能够使用的内存是原来的一半


3.先标记再整理

  标记-整理算法,思路就是先进行垃圾内存的标记,这个和标记-清除算法中的标记阶段一样。标记-整理算法会对内存区域进行整理,将当前的所有存活的对象移动到内存的一端,清理掉边界以外的内存,这样就可以得到一块连续的空闲内存空间了。

优点:盖住了复制算法的缺点,不会浪费一半的内存


4.分代搜集算法



新生代中的对象大部分的存活时间都很短,所以如果按照复制算法中的以1:1的方式来平分年轻代的话,会浪费很多内存空间。所以将年轻代划分为上图中所示的,一块较大的eden区和两块同等大小的survivor区,每次只使用eden区和其中的一块survivor区,保证了比例至少2:1,当进行内存回收的时候,会将当前存活的对象一次性复制到另一块空闲的survivor区上.

 HotSpot虚拟机默认Eden区和其中一块Survivor区的占比是8:1,通过JVM参数"-XX:SurvivorRatio"控制这个比值。SurvivorRatio的值是一个整数,表示Eden区域是一块Survivor区域的大小的几倍,所以,如果SurvivorRatio的值是8,那么Eden区和其中Survivor区的占比就是8:1,那么总的年轻代的大小就是(Eden + S0 + S1) = (8 + 1 + 1) = 10,所以年轻代每次可以使用的内存空间就是(Eden + S0) = (8 + 1)  = 9,占了整个年轻代的 9 / 10 = 90%,而每次只浪费了10%的内存空间用于复制

http://www.cnblogs.com/duke2016/p/6013519.html

老年代使用标记清理或者标记整理进行回收内存。


2.stack

后进先出。当一个线程被创建出来,这个栈也被跟着被创建出来。当线程被销毁时,栈也跟着被销毁了。方法的调用和方法的返回对应着栈帧入栈和出栈的操作。栈被线程私有,不能和其他线程使用,不存在线程安全的问题。可能的异常是stackOverflowError线程请求的栈深度超过虚拟机允许值和OutOfMemoryError

3.Method Area

常量,静态变量,优化后的代码

4.pc Registers

每个线程都有一个人pc register,是线程私有的。字节码解释器通过修改这里面的值来选择下一条要执行的指令,执行native方法,PC值为undefind

5.Native Method Stacks

其他语种的代码


java对象的结构:

1.header对象头

对象头主要用于对内服务,也就是为JVM服务的。目的是为该对象设置附加数据,方便识别和查找。分为markword和类型指针

markword存对象运行时数据,比如hashcode,GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳。难怪在看垃圾回收的时候,我还在郁闷,对象在内存中不都长一样吗,怎么还能分得出来呀

http://blog.csdn.net/u011277123/article/details/53259110

2.Instance Data实例数据

对象真正存的有效信息

3.padding对齐填充

根据JVM的设计,可以有也可以没有,让整个对象整齐(以8个字节的整数倍形式存在)


java对象的垃圾回收

1.新生代

新生代的对象在每次回收时都会有大量的对象死去,很少一部分存活,选择标记----复制算法

2.老年代

标记----清除或者标记----整理

3.永久代


0 0
原创粉丝点击