Java基础知识总结

6 篇文章 0 订阅
2 篇文章 0 订阅

Java基础知识总结

HashMap Key讨论

HashMap是存储键值对的数据结构,根据Key可以O(1)地获取值。但是有些内容是不适合作为key的,譬如可变对象。 可变对象是指创建后它的哈希值可以发生变化。

JVM

java内存管理方法区、堆、虚拟机栈、本地方法栈、程序计数器。其中方法区、堆是所有线程共享的;虚拟机栈、本地方法栈、程序计数器是各个线程自有的。

程序计数器:(program counter register)。一块很小内存空间,可看做是当前线程所执行的字节码的行号指示器。线程私有,每个线程的PC记录了当前线程要执行的指令。若当前线程执行的是Java方法,其PC值记录的是正在执行的虚拟机字节码指令的地址;若执行的是本地方法(native method),则PC为空(Undefined)。这是唯一一个没有规定任何OutOfMemoryError的区域。 Java虚拟机栈(VM Stack):线程私有,与线程生命周期相同。描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。对应2个异常:StackOverflowError。和OutOfMemoryError. 本地方法栈(Native Method Stack):线程私有,与VM Stack功能非常相似。用来存储线程调用本地方法时,本地方法的局部变量表,操作栈等信息。(HotSpot虚拟机直接把本地方法栈和虚拟机栈合二为一)。 Java堆(Heap):JVM管理内存最大一块;线程共享。在虚拟机启动时创建(可设置初始堆大小和最大堆大小:-Xms256M -Xmx512M),唯一目的就是存放对象实例,几乎所有的对象以及数组实例都在这里分配。Heap区是垃圾收集器管理的主要区域(GC堆)。 方法区(Method Area):线程共享。用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。别名Non-Heap(非堆)。其中运行时常量池(Runtime Constant Pool)是方法区的一部分。Class文件有一段信息描述常量池,这部分内容在类加载后进入方法区的运行时常量池中存放。

类加载机制

java采用双亲委派模型进行类加载。类加载器在加载类时,优先会向上级的类加载器递归查询——是否已经加载类,如果没有加载,将会自顶向下,尝试去加载这个类,直至成功加载。

启动类加载器(Bootstrap ClassLoader):负责将存放在JAVA_HOME\lib目录中的,或被-X bootclasspath参数所指定的路径中的,且是虚拟机识别的(仅按照文件名识别,如rt.jar,名字不符合的类库即使放在lib目录中也不会被加载)类库加载到虚拟机内存中。启动类加载器无法被Java程序直接使用。 扩展类加载器(Extension ClassLoader):由sun.misc.LauncherKaTeX parse error: Expected 'EOF', got '\lib' at position 30: …实现负责加载JAVA_HOME\̲l̲i̲b̲\ext目录中的,或者被Jav…AppClassLoader实现负责加载用户类路径上(ClassPath)所指定的类库;一般作为默认的类加载器

过程
  1. 加载
    负责将字节码文件以二进制的形式加载到内存中,创建类的class对象。

  2. 链接
    负责检查、准备、解析三个阶段;譬如静态变量的内存分配,类引用是否正确。

  3. 初始化
    类的初始化并不是初始化对象,而是根据代码中的值初始化类的静态变量值,类的静态变量的初始化方式也有直接在声明时指定值和在静态代码块中指定值两种方式

判断可回收对象
引用计数算法:

每个对象都有对应的引用计数器,当有一个地方引用该对象时,就将引用计数器的值加1,当引用失效时,就将引用计数器的值减1,当计数器的值为0时,表示对象没有引用,可以被回收了。

缺点:看起来简单高效,但是有循环引用问题。如果两个对象中包含对方的引用就会产生循环引用问题,导致垃圾收集器不能回收对象。

可达性分析算法:

如果对象与GC Roots 之间没有直接或间接的应用关系,就可以被回收了。常见的 GC Roots 对象包括虚拟机栈(栈帧本地变量表)中引用的对象、方法区中静态属性引用的对象、方法区常量引用的对象、本地方法栈中(Native 方法)引用的对象。GC Roots,是一个特殊的对象,且绝对不能被其他对象引用,不然也会像引用计数算法那样有循环引用的问题。

被启动类(bootstrap加载器)加载的类和创建的对象
jvm运行时方法区类静态变量(static)引用的对象
jvm运行时方法去常量池引用的对象
jvm当前运行线程中的虚拟机栈变量表引用的对象
本地方法栈中(jni)引用的对象
在这里插入图片描述
垃圾回收算法

  1. 标记清除
    标记出需要回收的对象,然后进行内容清除,内存回收。 缺点:产生内存碎片。

  2. 标记-复制
    将内存分为两部分,一部分空闲一部分使用。标记出存活的对象,将存活的对象复制到空闲的内存空间中;另外的一部分清理。 缺点:浪费一半的内存空降,当对象存活时间较高时,效率比较差;优点:无内存碎片。

  3. 标记-整理
    标记出存活的对象并移到另外一端,然后清理剩余的空间。无内存碎片。

  4. 年代算法
    根据对象存活时间的长短,将堆内存分为新生代和老生代,存活时间短的对象放在新生代区域,存活时间长的大对象(如对象数组)放在老生代区域。新生代和老生代的比例是 1 : 2,新生代又分为一个 Eden 区和两个 Survivor 区。新生代使用标记-复制算法,老生代使用标记-清除算法或标记-整理算法,这样最大发挥各自算法的优势。

回收器

  1. Serial 回收器
    Client端使用,采用标记复制算法实现的单线程垃圾回收器。

  2. ParalNew回收器
    Server端使用,采用标记复制算法实现的多线程垃圾回收器。

  3. CMS 回收器
    通过初始标记(Initial Mark)、并发标记(Concurrent Mark)、重新标记(Remark)、并发清除(Concurrent Sweep)四个步骤完成垃圾回收。重视服务器响应时间的服务器,比较适合。

  4. G1回收器
    标记复制算法,减少内存碎片。
    在G1之前的垃圾收集器,收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分(可以不连续)Region的集合。

在这里插入图片描述

不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。也就是不局限与jvm可以使用系统的内存。理论上取决于32位/64位系统可虚拟的内存大小。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值