java GC JVM

并行计算
        定义:称为平行运算,是相对于串行计算来说的。它是一种一次可以执行多个指令的算法,及通过问题求解规模,解决大型复杂的计算问题。
        分类:
            1.时间上的并行:指流水线技术
            2.空间上的并行:指多个处理器并发执行计算
        并行和并发的区别:
            都可以表示多个任务同时执行,但是侧重点不一样。
            并发则偏重于多个任务交替执行,多个任务可能是串行,而并行才是真正的意义上的同时执行。
    JVM的功能:
        执行main函数,还要做JIT编译,需要垃圾回收。无论是JIT编译,还是垃圾回收,在虚拟机内部都实现为一个单独的线程。
        ,这是因为业务的需要。因为这里的每一个任务都是相对独立的,不 应该将没有关联的业务代码拼凑在一起,
        分离为不同的线程更容易理解和维护。因此,使用井行也不完全出自性能的考虑,而有时候,我们会很自然地那么做。
    进程和线程:
        计算机上每一个运行的程序都是一个进程,而一个进程包含一到多个线程。进程 也可能是整个程序或者是部分程序的动态执行。
    内存泄漏:
        用动态存储分配函数动态分欸存储空间,在使用完后未被释放,使该内存一直被占用,一直到程序结束。这就是内存泄漏
        这里的存储空间并不是指物理内存,而是 指虚拟内存大小,这个虚拟内存大小取决于磁盘交换区设定的大小。
        由程序申请的一块内存, 如果没有任何一个指针指向它,那么这块内存就泄漏了。
        在 Java 程序里,如果发生内存泄漏,那么最后都会抛出 OutOfMemoryError 异常
        例子(在netbeans下测试):
            造成OOM的代码:
                    import java.util.HashMap;
                    import java.util.Map;
                  
                    /**
                     *
                     * @author xy7
                     */
                    public class outOfMemery {
                        static  class key{
                            Integer id;
                    
                             key(Integer id) {
                            }
                             @Override
                            public int hashCode(){
                                return id.hashCode();
                            }
                        }
                        public static void main(String[] args) {
                            Map m= new HashMap();
                            while (true) {
                                for(int i = 0;i<10000;i++){
                                    if(!m.containsKey(new key(i)));
                                    m.put(new key(i), "number"+i);
                                }
                            }
                        }
                    }
                运行上面的代码,会出现如下错误(outOfMemory)
                Exception in thread "main" java.lang.NullPointerException
                    at javaapplication1.outOfMemery$key.hashCode(outOfMemery.java:24)
                    at java.util.HashMap.hash(HashMap.java:339)
                    at java.util.HashMap.containsKey(HashMap.java:596)
                    at javaapplication1.outOfMemery.main(outOfMemery.java:31)
                C:\Users\xy7\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
                构建失败 (总时间: 0 秒)
        
        由于 GC 一直在发展,所以一般情况下,除非应用程序占用的内存增长速度非常快,造成 垃圾回收己经跟不上内存消耗的速度,
        否则不太容易出现 OOM 的情况。大多数情况下, GC 会 进行各种年龄段的垃圾回收,实在不行了就放大招,来一次独占式的 Full GC 操作
    java的引用:
        Java中的引用像C++的指针,通过引用可以对堆中的对象进行操作。最常见的就是强引用,也是默认的引用类型。
        在Java中,使用NEW 操作符新建一个新的对象,并将其值赋给一个变量的时候,这个变量就是指向该对象的一个强引用。
        在前面提到过,判断一个对象是否存活的标准为是否存在指向这个对象的引用l。
        在某函数 中创建对象,例如: StringBuffer 由= new StringBuffer(“Hello World" );
        ,假设该代码是在函数 体内运行的,那么局部变量 s位将被分配在枝内,而对象 StringBuffer 实例,被分配在 Java 堆上。
         局部变量由指向 StringBuffer 实例所在堆空间,通过由可以操作该实例,那么 s位就是 StringBuffer 的引用。此时,如果运行一个赋值语句:
        StringBuffer s位l=str;,那么,由所指向的 对象也将被 strl 所指向,同时在局部枝空间上会分配空间存放 strl 变量。
        此时, StringBuffer 实 例就有两个引用,而对引用使用“二”操作用于表示两个操作数所指向的堆空间地址是否相同, 
        不表示两个操作数所指向的对象是否相等。Java 中提供了 4 个级别的引用,即强引用( Strong Reference)、软引用(So位 Reference)、
        弱引用(Weak Reference)、虚引用(Phantom Reference)这 4 个级别。
        在这 4 个级别中只有强 引用类是包内可见的,其他 3 种引用类型均为 Public,可以在应用程序中直接使用,
        垃圾回收 器会尝试回收只有弱引用的对象。
    finalization机制:
        Java 语言提供了对象终止(finalization) 机制来允许开发人员提供对象被销毁之前的自定义 处理逻辑。 
        Object 类提供了 finalize 方法来添加自定义的销毁逻辑。如果一个类有特殊的销毁逻 辑,可以覆写 finalize 方法。
        从功能上来说, finalize 方法与 C++中的析构函数比较相似,但是 Java 采用的是基于垃圾回 收器的自动内存管理机制
        ,所以 finalize 方法在本质上不同于 C++中的析构函数。当垃圾回收器 发现没有引用指向一个对象时, 会调用这个对象的 finalize 方法
        。通常在这个方法中进行一些资 源释放和清理的工作,比如关闭文件、套接字和数据库连接等。
        由于 finalize 方法的存在,虚拟机中的对象一般处于三种可能的状态。第一种是可达状态, 当有引用指向该对象时,该对象处于可达状态。
        根据引用类型的不同,有可能处于强引用可达、 软引用可达或弱引用可达状态。第二种是可复活状态,如果对象的类覆写了 finalize 方法
        ,则对 象有可能处于该状态。虽然垃圾回收器是在对象没有引用的情况下才调用其 finalize 方法,
        但是 在 finalize 方法的实现中可能为当前对象添加新的引用。因此在 finalize 方法运行完成之后,垃 圾回收器需要重新检查该对象的引用
        。如果发现新的引用,那么对象会回到可达状态,相当于 该对象被复活,否则对象会变成不可达状态。当对象从可复活状态变为可达状态之后,
        对象会 再次出现没有引用存在的情况。在这个情况下, finalize 方法不会被再次调用,
        对象会直接变成 不可达状态, 也就是说,一个对象的 finalize 方法只会被调用一次。 第三种是不可达状态,
        在这 个状态下,垃圾回收器可以自由地释放对象所占用的内存空间。

猜你喜欢

转载自blog.csdn.net/qq_38483191/article/details/82391709