• Java总结


    Java虚拟机:

    Class Loader:依据特定格式,加载class文件到内存;

    Execution Engine:对命令进行解析;

    Native Interface:融合不同开发语言的原生库为Java所用;

    Runtime Data Area:JVM内存空间的结构模型;

    Java反射:

    Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

    对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

    类从编译到到执行的过程:

    1.编译器将name.java源文件编译为name.class字节码文件;

    2.ClassLoader将字节码转换为JVM中的Class<name>对象;

    3.JVM利用Class<name>对象实例化为name对象;

    ClassLoader:

    ClassLoader 在Java中有着非常重要的作用,它主要工作在Class装载的加载阶段,其主要作用是从系统外部获得Class二进制数据流。

    它是Java的核心组件,所有的Class都有ClassLoader进行加载,ClassLoader 负责通过将Class文件里的二进制数据流装载进系统,然后

    交给Java虚拟机进行连接,初始化等操作。

     类加载器的双亲委派机制:

    .......

    避免多份同样字节码的加载;

    LoadClass 和forName的区别;

    类的装载过程:

    JVM内存模型:

    线程私有:

      1.程序计数器

        当前线程所执行的字节码行号指示器(逻辑)

        改变计数器的值来选取下一条需要执行的字节码指令

        和线程是一对一的关系即“线程私有”

        对Java方法计数,如果是Native方法则计数器值为Undefined

        不会发生内存泄露

      2.虚拟机栈

        Java方法执行的内存模型

        包含多个栈帧

        (局部变量表:包含方法执行过程中的所有变了;操作栈:入栈,出栈,复制,交换,产生消费变量;动态链接,返回地址)

        递归引发java.lang.StackOverflowError异常:递归过深,栈帧超出虚拟栈深度;

      3.本地方法栈

        与虚拟机栈相似,主要作用于标注了native的方法;

    所有线程共享:

    1.MetaSpace(类加载信息OOM)

    2.堆(数组和类对象OOM)常量池(字面量和符号引用量OOM)

    MetaSpace相比PermGen的优势:

    1.字符串常量池存在永久代中,容易出现性能问题和内存溢出;

    类和方法的信息大小难以确定,给永久代大大小指定带来困难;

    永久代会为GC带来不必要的复杂性;

    方便HotSpot与其他JVM如Jrockit的集成;

    Java 堆(Heap):

      对象实例的分配区域

      GC管理的主要区域

    JVM三大性能调优参数-Xms -Xmx -Xss

    java -Xms 128m -Xmx 128m -Xss 256k -jar xxxx.jar

    -Xss:规定了每个线程虚拟机栈(堆栈)的大小

    -Xms:堆初始值

    -Xmx:堆能达到的最大值

    Java内存模型中堆和栈的区别-内存分配策略

    静态存储:编译时确定每个暑假目标在运行是的存储空间需求;

    栈式存储:数据区需求在编译时未知,运行时模块入口前确定;

    堆式存储:编译时或运行时模块入口都无法确定,动态分配;

    Java内存模型中堆和栈的区别-联系

    联系:引用对象,数组时,栈里定义变量保存堆中目标的首地址;

    管理方式:栈自动释放,堆需要GC;

    空间大小:栈比堆小;

    碎片:栈产生的碎片远小于堆;

    分配方式:栈支持静态和动态分配,而堆仅支持动态分配;

    效率:栈的效率比堆高;

    元空间,堆,线程独占部分的联系-内存角度

    元空间:类信息

    Java堆:类对象

    线程独占:变量引用,参数引用,本地变量

    引用计数法:

    通过判断对象的引用数量来决定对象是否可以回收;

    每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1;

    任何引用计数为0的对象实例可以被当做垃圾回收;

    优点:执行效率高,程序执行受影响较小;

    缺点:无法检测出循环引用的情况,导致内存泄露;

    可达性分析算法:

    通过判断对象的引用链是否可达来决定对象是否可以被回收;

    可作为GC Root的对象:

    虚拟机栈中引用的对象(栈帧中的本地变量表)

    方法区中的常量引用的对象;

    方法区中的类静态属性引用的对象;

    本地方法栈中JNI(Native方法)的引用对象;

    活跃线程的引用对象;

    垃圾回收算法:

    标记清除算法(Mark and Sweep)

    标记:从根集合进行扫描,对存活的对象进行标记;

    清除:对堆内存从头到尾进行线性遍历,回收不可达对象内存;

    --

    存在碎片化问题;

    复制算法(Copying)

    分为对象面和空闲面;

    对象在对象面上创建;

    存活的对象呗从对象面复制到空闲面;

    将对象面所有对象内存清除;

    --

    解决了碎片化问题;

    顺序分配内存,简单高效;

    适用于对象存活率低的场景;

    标记整理算法(Compacting)

    标记:从根节点进行扫描,对存活的对象进行标记;

    清除:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收;

    --

    避免了内存的不连续行;

    不用设置两块内存互换;

    适用于存活率高的场景;

    分代收集算法(Generational Collector)

    1.垃圾回收算法的组合

    2.按照对象生命周期的不同划分区域以采用不同的来及回收算法;

    年轻带:尽可能快速低收集掉那些生命周期短的对象;1/3堆空间

    Eden区 8/10

    两个Survivor区1/10,1/10

    老年代:2/3堆空间

    Full GC和Major GC

    Full GC比Minor GC慢,但执行频率低;

    常用调优参数

    -XX:SurvivorRatio:Eden和Survivor的比值,默认8:1

    -XX:NewRatio:老年代和年轻带内存大小的比例

    -XX:MaxTenuringThreshold:对象从年轻带晋升到老生带经过GC次数的最大阈值;

    GC分类

    Minor GC

    Full GC

    触发Full GC的条件:

    老年代空间不足;

    永久代空间不足;

    CMS GC时出现promotion failed,concurrent mode failuer

    Minor GC晋升到老年代的平均大小大于老年代的剩余空间;

    调用System.gc()

    使用RMI来进行RPC或管理的JDK应用,每小时执行1次Full GC;

    Stop-the-World:

    JVM由于要执行GC而停止了应用程序的执行;

    任何一种GC算法都会发生;

    多数GC优化通过减少Stop-the-World发生的时间来提高程序性能;

    Safepoint:

    分析过程中,对象引用关系不会发生变化的点;

    产生Safepoint的地方:方法调用;循环跳转;异常跳转等;

    安全点数量得适中;

    JVM运行模式:检查方法,java -version

    server

    clinet

     年轻代垃圾收集器:

    Serial收集器(-XX:+UseSerialGC,复制算法)

    单线程收集,进行垃圾收集时,必须暂停所有工作线程;

    简单高效,Client模式下默认的年轻代收集器;

    ParNew收集器(-XX:UseParNewGC,复制算法)

    多线程收集,其余的行为,特点跟Serial收集器一样;

    单核执行效率不如Serial,在多核下执行才有优势;

    Paralel Scavenge收集器(-XX:+UseParallel GC,复制算法)

    比起关注用户线程停顿时间,更关注系统的吞吐量;

    在多核下执行才有优势,Server模式下默认的年轻代收集器;

    ----------------------------------------------------------------------------------

    老年代垃圾收集器

    Serial Old收集器(-XX:+UseSerialOldGC,标记-整理算法)

    单线程收集,运行垃圾收集时,必须暂停所有工作线程;

    简单高效,Client模式下默认的老年代收集器;

    Parallel Old收集器(-XX:+UseParallelOld GC,标记-整理算法)

    多线程,吞吐量优化;

    CMS收集器(-XX:UseConcMarkSweepGC,标记-清除算法)

    初始标记:stop-the-world

    并发标记:并发追溯标记,程序不会停顿;

    并发预清理:查找执行并发标记阶段从年轻代晋升到老年代的对象;

    重新标记:暂停虚拟机,扫描CMS堆中的剩余对象;

    并发清理:清理垃圾对象,程序不会停顿;

    并发重置:重置CMS收集器的数据结构;

    G1收集器(-XX:UseG1GC,复制+标记-整理算法)

    Garbage First收集器的特点:

    并行和并发

    分代收集

    空间整合

    可预测的停顿

    将整个Java堆内存划分成多个大小相等的Region;

    年轻代和老年代不再物理隔离;

    Object的finalize()的方法的作用

    ......

    Java中的强引用,软引用,弱引用,虚引用的作用:

    强引用(Strong Reference)

    软引用(Soft Reference)

    弱引用(Weak Reference)

    虚引用(Phantom Reference)

    进程是资源分配的最小单位,线程是CPU调度的最小单位;

    所有与进程相关的资源,都被记录在PCB中;

    进程是抢占处理机的调度单位;线程属于某个进程,共享其资源;

    线程只由堆栈寄存器,程序计数器和TCB组成;

    总结:

    线程不能看做独立应用,而进程可看做独立应用;

    进程有独立的地址空间,相互不影响,线程只是进程的不同执行路径;

    线程没有独立的地址空间,多进程的程序比多线程程序健壮;

    进程的切换比线程的切换开销大;

    Java对操作系统提供的功能进行封装,包括进程和线程:

    运行一个程序产生一个进程,进程包含至少一个线程;

    每个进程对应一个JVM实例,多个线程共享JVM里面的堆;

    Java采用单线程编程模型,程序会自动创建主线程;

    主线程可以创建子线程原则上要后与子线程完成执行;

    Thread中的start和run方法的区别:

    调用start()方法会创建一个新的子线程并启动;

    run()方法只是Thread的一个普通方法的调用;

    Thread和Runnable的关系:

    Thread是实现了Runnable接口的类,使得run支持多线程;

    因类的单一继承原则,推荐多使用Runnabe接口;

     如何给run()方法传参

    实现的方法主要有三种

    构造函数传参

    成员变量传参

    回调函数传参

    如何实现处理线程的返回值?

    实现的方式主要有三种

    1.主线程等待法

    2.使用Thread类的join()阻塞当前线程以等待子线程处理完毕;

    3.通过Callable接口实现:通过FutureTask Or线程池获取;

    线程的六个状态:

    1.新建(New):创建后尚未启动的线程的状态;

    2.运行(Runnable):包含Running和Ready;

    3.无限期等待(Waiting):不会被分配CPU执行时间,需要显示被唤醒;

    4.限期等待(Timed Waiting):在一定时间后会由系统自动唤醒;

    5.阻塞(Blocked):等待获取排它锁;

    6.结束(Terminated):已终止线程的状态,线程已经结束执行;

    Sleep 和Wait的区别:

    基本的差别:

    1.sleep是Thread类的方法,wait是Object类中定义的方法;

    2.sleep()方法可以在任何地方使用;

    3.wait()方法只能在synchronized方法或synchronized块中使用;

    最主要的本质区别:

    Thread.sleep只会让出CPU,不会导致锁行为的改变;

    Object.wait不仅让出CPU,还会释放已经占有的同步资源锁;

    notify和notifyAll 的区别:

    ...

    yield:

    ...

    如何中断线程:

    ...

    synchronized

    synchronized和ReentrantLock的区别:

    ...

    Java内存模型JMM:

    JMM的中内存和工作内存:

    JMM如何解决可见性问题:

    volatile

    volatile和synchronized的区别;

    Java线程池

  • 相关阅读:
    Codeforces 758D:Ability To Convert(思维+模拟)
    Codeforces 758B:Blown Garland(模拟)
    BZOJ-1053 反素数
    BZOJ-1024 生日快乐
    BZOJ-1036 树的统计
    BZOJ-1029 建筑抢修
    BZOJ-1059 矩阵游戏
    BZOJ-1026 windy数
    BZOJ-1019 汉诺塔
    BZOJ-1031 字符加密
  • 原文地址:https://www.cnblogs.com/songyuejie/p/12594218.html
Copyright © 2020-2023  润新知