• 深入理解Java虚拟机


            首先需要澄清的是,垃圾收集(GC)的历史远比Java要久远,当我们意识到手动管理内存所带来的麻烦时,懒惰的天性推动先驱们寻找更为简单、易用、关键是傻瓜式的内存管理技术。GC技术起源于1960年诞生于MIT的Lisp语言,由此可见越聪明的人越懒惰。

     
            最近有一种想法:程序开发,程序设计从本质上来讲是个哲学问题,虽然我们要解决的问题是现实在程序世界中的投射,那么问题本身就应该在现实世界中有相应的解决,而且我们也一直在模拟现实世界,由过程式,面向对象以及函数式编程以及我们下面所要看到的GC的设计思想可见。
     
            因为不想根据运行环境的不同修改代码,我们希望有一个缓冲层能屏蔽底层硬件环境的不同,于是我们引入了JVM
     
            因为有人工管理内存存在的不确定,JVM的设计者们引入了内存自动分配与垃圾收集
     
            因为想要最大限度的利用内存,JVM内存被划分为线程内存(栈)与共享内存堆
     
            为了能够更有效的分配及回收内存,堆被划分成了新生代与老年代,这样才能根据对象的不同采用更加具有效率的GC方案。
     
            也是因为不同GC方案的需求,新生代又被划分为Eden区和survivor区
     
            |---------- 新生代------------|------老年代------|
            |Eden|survivor|survivor|          old             |
     
            ....
     
            1. 程序计数器、虚拟机栈、本地方法栈三个区域随这线程生死,其内存分配都具有确认性,因此不必过多考虑,我们所说的内存分配与回收通常是指的堆
     
            2. 我们怎么判断一个对象”死了“,也就是可以回收的
     
                    2.1 引用计数器方法(未使用)
     
                            最直观的方法,对象如果被引用,则引用计数+1,如果去引用,则引用计数-1,如果为0,则对象没有引用,可以被回收。但该算法无法解决循环引用的问题。JAVA虚拟机也没有采用该算法。
     
                    2.2 根搜索算法 GC Root Tracing(Java、C#、Lisp)
     
                            通过一系列的名称”GC Root“的对象作为起始点,从该节点向下搜索,走过的路径称为引用链,所有不在任意一条引用链上的对象(不可达)就可以判断为不可用。
     
                            该算法需要确定Root点,在JAVA中包括如下几种:虚拟机栈中本地变量表所引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象、本地方法栈JNI中引用的对象
     
                    2.3 finalize
     
                            在finalize块中我们可以设置对象被重新引用,从而躲过GC,但不推荐在Finalize快中进行任何操作。因在finalize中的代码块会被放置在一个队列中执行,且不保证执行结果。
     
                           
     
            3. 引用
     
                    Java的引用可以分为强引用(Strong Reference)、软引用(SoftReference)、弱引用(WeakReference)、虚引用(PhantomReference)这四种,并且引用是由强到弱。
     
                    强引用是代码中普遍存在的,类似于Object obj = new Obeject()类的引用,其永远不会被回收
     
                    软引用用来描述一些还有用,但并非必须的对象,在发生内存溢出前,会对软引用的对象进行二次回收,仍无法分配内存时才会抛出异常。
     
                    弱引用用来描述非必须对象,被弱引用关联的对象智能生存到下一次GC之前
     
                    虚引用是最弱的引用关系,其不会对对象产生影响,其设置的唯一目的就是在对象被回收时收到一个系统通知。
     
            4. 方法区的回收
     
                    方法区也是有垃圾收集的,只是效果通常不好。方法区(永久代)的垃圾收集主要包括两部分内容:废弃常量和无用的类。在大量使用反射、动态代理、GClib等bytecode的场景都需要虚拟机的卸载功能,以保证方法区不会溢出。
     
  • 相关阅读:
    洛谷P1199三国游戏
    Cracking the Coding Interview 6.2
    Cracking the Coding Interview 5.2
    Cracking the Coding Interview 5.7
    洗牌算法
    字符串排列组合问题
    指针作为形参
    KMP算法代码
    搜索二叉树
    面试题集锦
  • 原文地址:https://www.cnblogs.com/jiyuqi/p/4354138.html
Copyright © 2020-2023  润新知