标签:
《深入理解Java虚拟机》第二三章摘要
Java内存区域与内存溢出
Java虚拟机中的内存分配图:
各个区域的特性总结如下表:
补充说明:
内存分配方式:虚拟机使用哪种方式由内存是否规整决定,而内存是否规整则由回收算法决定。
对象在HotSpot虚拟机中的内存布局如下表所示:
在Java规范中,对于reference类型只规定了一个指向对象的引用,但没有规定通过何种方式去访问引用的数据。因此对于不同的虚拟机也有不同的访问方式,主要有两种方式:
两种使用方式的图示说明如下图:图片来源 http://www.th7.cn/Program/java/201604/846729.shtml
垃圾回收算法
判断一个对象是否死去,不可能再被用的算法有两种:
可以作为GC Roots的对象有:
在Java中有四种引用强度:
系统的GC工作流程如下图所示,总的来说,一个对象被回收可能会经过两次标记过程,并且可能在finalize方法中拯救自己以避免被回收。
几种典型的垃圾回收算法:
HotSpot VM中的垃圾回收算法的具体实现细节:为了结果的准确,GC在扫描时是需要冻结所有线程的。目前主流的Java虚拟采取的都是准确式GC,即系统知道每个内存位置的数据到底是一个什么数据类型,以HotSpot为例,它采取的是一个叫做OopMap的数据结构来实现这样的映射记录。有了这样的信息,虚拟机就直接知道哪些地方存放着对象的引用,从而避免了对内存挨个的检查,加快了GC扫描的速度。程序的每条指令都可能导致引用关系或者内存数据的变化,即会导致OopMap的变化,这样的话,如果给每个指令都生成一个对应的OopMap数据那么是相当占用空间的,于是提出了安全点的概念(SafePoint),即只有当每个线程都运行到线程对应的安全点时才进行GC扫描,从而也只要给安全点上的指令生成OopMap即可,这样就减少了OopMap的数量。而安全点的选取要考虑到GC频率与系统性能的综合影响,一般选取方法调用、循环跳转、异常跳转等“具有让程序长时间运行的特征”的点。为了让线程都跑到安全点停顿下来以进行GC扫描,有抢先式中断和主动式中断两种方式。这里又有另外一个问题,如果遇到一个比如处于Sleep状态的线程,那么它是不会走动的,如果它恰好不是在一个安全点Sleep,那么意味着它永远不会走到安全点来,所以又提出了安全区域(SafeRegion)的概念。即在这个区域内的点都是安全点。线程进入安全点之后会标志自己进入了安全区域,且必须等GC执行完了才会离开安全区域。
各个垃圾回收器:
几条最普遍的内存分配规则:
标签:
原文地址:http://www.cnblogs.com/willhua/p/5975726.html