一、Java内存泄漏
1、内存泄漏种类
Java使用的内存种类包含三种,这三种类型的内存都可能发生内存泄漏
- 堆内存泄漏,如果JVM 不能在java 堆中获得更多内存来分配更多java 对象,将会抛出java堆内存不足(java OOM) 错误。如果java 堆充满了活动对象,并且JVM 无法再扩展java 堆,那么它将不能分配更多java 对象。更多情况是程序设计有问题,生成的对象占用过多的堆内存造成堆内存泄漏。
- 本地内存泄漏, 如果JVM 无法获得更多本地内存,它将抛出本地OOM错误。当进程用到的内存到达操作系统的最大限值,或者当计算机用完RAM 和交换空间时,通常会发生这种情况。当发生这种情况时,JVM处于本地内存OOM状态,此时虚拟机会打印相关信息并退出。本地内存泄漏根本原因是Java调用本地库或方法,这些本地库中的API有内存泄漏。
- 加载类(字节码)的Perm内存不足.即指定的 Permsize 不足以加载系统运行使用的.class字节码文件,就发发生Perm内存不足的错误。
2、解决问题
JVM内存泄漏问题的解决相对来说比较简单。
- 使用下面的命令dump出JVM内存映像
jmap -dump:format=b,file=mydump.bin pid
生成的dump文件会比较大,比JVM配置的堆大小相当 - 使用内存泄漏工具分析这个dump文件,内存泄漏工具有很多,在百度上一搜就能搜到很多,如MemoryAnalyzer.exe
从工具分析生成的分析结果可以很容易找到占用内存最多的对象,结合程序分析这个对象在程序中的使用,一般很容易就定位出内存泄漏的原因。
3、小结
定位问题和分析问题时下面的工具就可以定位问题和解决问题。
–linux的top命令
–JDK自带的工具jstat和jmap
–JVM内存泄漏工具
JVM内存泄漏问题的处理相比C程序内存泄漏更好定位和解决,主要原因是Java有更好用的诊断和分析工具。
对于本地内存泄漏,上述分析方法就不灵了。本地内存泄漏用JDK的工具(如jstat和jmap)是无法找到原因的。解决这类问题还得用解决C程序内存泄漏的方法多定位和分析,结合操作系统日志和命令及一些经验技巧来解决。
二、平衡树
平衡二叉搜索树
它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。常用算法有红黑树、AVL、Treap、伸展树等。在平衡二叉搜索树中,我们可以看到,其高度一般都良好地维持在O(log2n),大大降低了操作的时间复杂度。
调整平衡的基本思想:
当在二叉排序树中插入一个节点时,首先检查是否因插入而破坏了平衡,若破坏,则找出其中的最小不平衡二叉树,在保持二叉排序树特性的情况下,调整最小不平衡子树中节点之间的关系,以达到新的平衡。
所谓最小不平衡子树,指离插入节点最近且以平衡因子的绝对值大于1的节点作为根的子树。先插入指定节点,记录下当前节点的信息,LH,EH或者RH。
- 若左子树高LH,查看其左子树根节点的信息,若是LH,则一次右旋;若是RH,则一次左旋+一次右旋
- 若右子树高RH,查看右子树根节点的信息,若是RH,则一次左旋;若是LH,则一次右旋+一次左旋
- 调整改变的节点信息
追求绝对的高度平衡,随着树的高度的增加,动态插入和删除的代价也随之增加
1、红黑树
红黑树(Red Black Tree) 是一种自平衡二叉查找树
红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。 二叉平衡树的严格平衡策略以牺牲建立查找结构(插入,删除操作)的代价,换来了稳定的O(logN) 的查找时间复杂度 ,它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。
O(log n)时间内做查找,插入和删