码迷,mamicode.com
首页 > 其他好文 > 详细

运行时内存

时间:2017-09-25 00:59:22      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:roots   finalize   没有   连续   编译   调用   用户交互   内存泄漏   覆盖   

1 程序计数器 线程私有,记录线程所执行的字节码行号指示器。

2 虚拟机栈  描述Java方法执行内存模型 , 进入一个方法创建栈帧。

3 Java堆   存放对象实例

4 方法区:编译后的代码数据,包括加载 的类信息,常量,静态变量。

5 常量池 :class文件常量池方法区一部分存放编译器生成的字面量和符号引用,加载时放入虚拟机的运行时常量池中

6 对像创建 : 1 类是否已经加载   2 为对象分配内存 类加载后,对象所需内存确定 , 内存空间初始化0,3 设置对象头部信息 (对象所属类,哈希等) 4 根据程序员意愿,执行init方法,为对象设置初值。

7 对象布局: 对象头(1 对象运行时数据  2 类型指针 数组还有数组长度), 实例数据信息  , 对其填充

8 对象访问定位  1 句柄 (对象数据指针   对象类型指针) 好处,reference存稳定句柄值,对象变化只改变句柄中对象数据指针,  2 直接  对象地址,好处  访问块。

9分析是内存溢出还是内存泄漏,如果内存泄漏,找出泄漏对象到GC roots的引用链,看为什么对象没有回收, 如果是内存溢出,看虚拟机堆是不是太小。看某些对象生命周期是否过长,尝试减少运行期间内存消耗。

 10 哪些内存需要回收。Java堆,方法区

11 什么时候需要回收 对象死

       1 引用计数算法:每一个地方引用对象,计数器加1 , 很难解决对象之间相互循环引用问题。

       2 可达性分析  “GC Root” 对象为起点,从起点向下搜,所走过路径为引用链,当对象到“GC Root” 没有引用链时,对象不可达。

12 生存还是死亡    不可达对象, 检测对象是否有必要执行finalize方法,如果没有覆盖finalize方法或方法已经被虚拟机调用过,会直接回收,如果有必要执行方法,在这个方法中对象有可能存活。

技术分享
public class JDBCTest{
    public static JDBCTest j = null;
    
    public void isAlive() {
        System.out.println(" i am alive");
    }
    
    @Override
    protected void finalize() throws Throwable {
        // TODO Auto-generated method stub
        super.finalize();
        System.out.println("finalize exet");
        j = this;
    }
    public static void main(String[] args) throws Exception {
        j = new JDBCTest();
        j = null;
        System.gc();
        Thread.sleep(500);
        if (j != null) {
            j.isAlive();
        } else {
            System.out.println("j dead");
        }
        
        j = new JDBCTest();
        j = null;
        System.gc();
        Thread.sleep(500);
        if (j != null) {
            j.isAlive();
        } else {
            System.out.println("j dead");
        }
        
    }
}
View Code

13 回收方法区   1 废弃常量,无用类    1 类实例被回收  2 类classloader被回收 3 Class对象没有被引用

14 垃圾回收算法

           1 标记 -清除   缺点 标记,清除效率不高  产生大量不连续碎片 

            2复制 分为大的eden和小的survivor  只用Eden ,垃圾回收时将存活对象放入survivor ,并清除Eden

           3 标记 -- 整理  对垃圾回收后大部分对象都会存活使用   和标记-清除不同的是,让存活对象像一边移动,清除边界外内存。

           4 分代收集   根据对象存活周期不同,新生代 ,每次垃圾收集都有大量对象死,使用复制算法   老年代 对象存活率高,标记清理或标记整理

15 hotSpot算法实现

      1 枚举根节点(全局性引用,常量或静态属性   与执行上下文 栈帧本地变量表)stop the world  枚举跟节点时,必须停止所有线程,否则枚举不准确 ,编译类后使用oopMap数据结构记录哪个地方有引用,加快枚举跟节点速度

     2 安全点  在安全点停下来GC, 是否有让程序长时间执行的特征  方法调用 ,循环跳转  异常跳转 

       如和在GC发生时让线程在安全点停下,1 抢占式  中断所有线程,如果发现有线程没有到安全点,线程跑到安全点  2 主动中断 在安全点轮询,如果需要GC,把自己中断。

     3 如果线程处于sleep或阻塞,线程无法相应jvm中断请求,走不到安全点,需要安全区域:在这段代码片段中,引用关系不发生变化,任意地方开始GC安全。在线程要离开安全取时,检测是否完成枚举跟节点。

   技术分享

 serial  新生代  垃圾收集时必须停止所有线程工作。并且只有一条线程垃圾回收  client模式默认

 ParNew  serial 多线程版本 , 可以有多条线程垃圾回收  server模式默认

parallel scavenge 和ParNew 很相似 , 多条线程垃圾回收 , 和上一个关注停顿时间不同,主要关注吞吐量(用户代码运行时间/总运行时间),适合和用户交互少的后台代码执行。可以直接设置吞吐量和最大停顿时间。

老年代

 serial old    serial老年代版本,单线程收集, 标记整理, client模式

Paraller old 是parallel scavenge老年代版本 多线程收集 在注重吞吐量和CPU资源敏感场合,优先Paraller old ,parallel scavenge组合

 cms (concurrent mark sweep) 以获取最短回收停顿为目标,标记清除算法,

技术分享

4个步骤 初始,重新 stop the world , 初始标记只标记GC Root直接关联对象,速度很快   并发标记 经行GC Roots Tracing过程,重写标记修正并发标记期间的修改,

 缺点1  cms对CPU资源敏感  2 无法处理浮动垃圾 可能出现concurrent  mode failure 失败导致另一次full gc,由于cms并发清理阶段用户线程还在运行着,伴随程序运行还有垃圾产生,垃圾出现标记过程后,cms无法在当次处理他们,只好下次gc,这部分垃圾为浮动垃圾 3  空间碎片

G1 

技术分享

并行 :多条垃圾回收线程一起执行

并发 :垃圾回收,用户程序一起执行

内存分配与回收策略

 

运行时内存

标签:roots   finalize   没有   连续   编译   调用   用户交互   内存泄漏   覆盖   

原文地址:http://www.cnblogs.com/whesuanfa/p/7588014.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!