主页

垃圾收集与内存分配

对象死亡判断算法 引用记数法 在对象中添加一个引用计数器, 每当有一个地方引用它时, 计数器值就加一; 当引用失效时, 计数器值就减一; 任何时刻计数器为零的对象就是不可能再被使用的。 尽管原理简单,判断效率高,但是有很多情况是欠缺考虑的,比如两个废弃对象之间互相引用,虽然两个对象不会再使用,但是引用计数器不会为0,但是它们实质上是应该被清理的。 可达性分析 这个算法的基本思路就是通过一系列称为“GC Roots”的根对象作为起始节点集, 从这些节点开始, 根据引用关系向下搜索, 搜索过 程所走过的路径称为“引用链”(Reference Chain) , 如果某个对象到GC Roots间没有任何引用链相连,或者用图论的话来说就是从GC Roots到这个对象不可达时, 则证明此...

阅读更多

JVM内存分区

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。 这些区域有各自的用途, 以及创建和销毁的时间, 有的区域随着虚拟机进程的启动而一直存在, 有些区域则是依赖用户线程的启动和结束而建立和销毁。 程序计数器 线程私有内存,生命周期与线程相同。它可以看作是当前线程所执行的字节码的行号指示器,记录的是正在执行的虚拟机字节码指令的地址。它是唯一一个不会出现OutOfMemoryError 的区域。 虚拟机栈 线程私有内存,生命周期与线程相同。在每个方法执行的时候,Java虚拟机都会同步创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。口头中的栈通常指的是虚拟机栈中的局部变量表。 局部变量表中存放了编译期间可知的基本数据类型(boo...

阅读更多

对象探秘——HotSpot虚拟机

对象的创建 当虚拟机遇到一条字节码new指令时,虚拟机的步骤: 检查这个指令的参数是否能在常量池中定位大盘一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、 解析和初始化过。 如果没有, 那必须先执行相应的类加载过程 在类加载检查通过后, 接下来虚拟机将为新生对象分配内存,对象所需内存的大小在累加载完成之后可完全确定。 假设Java堆中内存是绝对规整的,那么可以将指针向空闲空间方向挪动一段对象大小的距离,这称为指针碰撞;但如果Java堆中的内存并不是规整的, 已被使用的内存和空闲的内存相互交错在一起 ,虚拟机会维护一个空闲列表,从列表中找到一块空间划分给对象实例。Java堆是否规整由垃圾处理器是是否带有空间压缩整理能力决定。 ...

阅读更多

构造大顶堆

构造大顶堆 由于树结构存在next指针等数据,因此使用树结构构造大顶堆往往比较吃内存。由于堆结构为完全二叉树,仅使用数组即可构造大顶堆,父节点与左右子节点位置关系为: 父节点 arr[i],左子节点 arr[2* i],右子节点arr[2* i+1] 完全二叉树中 叶子节点数量=非叶子节点数量(+1),是否+1视这颗完全二叉树是否以左子树结束 在构造大顶堆时,以最底层最后一个非叶子节点开始构造(下图为了避免节点不是那么拥挤,将结尾的左子树移到了右子树) (1) (2) (3) (4) public int[] sortArray(int[] nums) { buildHeap(nums,nums.length); ...

阅读更多

自动装箱与自动拆箱

自动装箱与自动拆箱是Java针对基础类型与包装类互相转换而设定的机制 java是面向对象语言,为了使用方便,提供了八种基本数据类型供我们使用,同时也有与其对应的八种引用类型 基本类型 大小 数值范围 默认值 包装类 boolean 只有1 bit有用信息,所占空间没有严格说法 {true,false} false Boolean byte 8 bit [-2^7, 2^7-1] 0 Byte char ...

阅读更多

二叉树遍历

二叉树遍历是二叉树中最基本也是最重要的算法 二叉树遍历算法有: 前序遍历:依据 中-左-右 顺序对二叉树进行遍历节点 中序遍历:依据 左-中-右 顺序对二叉树进行遍历节点 后续遍历:依据 左-右-中 顺序对二叉树进行遍历节点 层序遍历:依据二叉树的深度,从上到下,在每层中依据从左到右的顺序遍历节点 二叉树结构代码 class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() {} TreeNode(int val) { this.val = val; } TreeNode(int val, TreeNode left, Tre...

阅读更多