**1.===============**
2.伟大的环卫工人
C语言中需要自己手动释放内存而java不需
容易导致程序奔溃,不适合大型项目
1.如何发现垃圾-1
引用计数器
最原始的一种 “引用计数器”
就是当一个对象被赋值给一个变量时,引用计数+1;
持有引用的变量退出作用域是,引用计数-1;
如果发现引用对象时0那么就会被清理掉
代码实现:
看完实现代码后 他们分别是1和1 所以不算是垃圾 往远处想:当main方法退出的话那么他们就为0了所以就可以被清除了
更进一步
2.如何发现垃圾-2
根搜索算法(GC Root)
栈帧里的局部变量所引用的对象;
方法区的静态变量和常量所引用的对象;
3.环卫工人也要与时俱进
1.标记清理算法(简单),缺点是内存碎片多,使用效率不高
分段复制算法
把要用的分成2半,如果要清理的话就把空闲那一半需要保留的对象复制到空闲那片区域,用一半留一半,然后把要清理的清理掉
缺点:动静太大
标记整理算法
比较复杂,每次清理完都要整理一遍
以上算法都有缺点不智能 有些麻烦,一个对象被清理几次发现还在就会一直用下去,每次都判断是不是垃圾 导致效率不高,这些都不是最高效的算法
分代收集算法-1
它可以做到不用挪来挪去,伊甸园生命周期较短(短命)
分段复制法生命周期比较长,是中等的,经过15次还存活的话那就会一直使用它,移至 标记-整理法(老年代),永久代一般都不会被清理(方法区)
打比方打扫卫生也分级别
清理垃圾
4.如何编写高效、健壮的Java程序
尽量不要在循环中: 使用try…catch、new 对象;
把频繁使用的短命对象缓存起来;
尽可能使用栈内变量(方法内局部变量)
不要用异常来控制代码流程
用线程池、连接池,不要自己创建
学会读Java核心API源代码
5.内存泄漏与内存溢出
内存泄漏:该回收的内存/对象,无法回收导致内存一直占用
内存溢出:内存不够了,导致程序奔溃
内存泄漏-1例子:
内存泄漏-例子
6.实操:干掉JVM
省咯
------------------------总结以下斜体样式------------------------------
内存模型中几个重要区域的作用?
方法区:类class信息、静态属性、常量等堆:对象(数组也是对象)
栈:线程执行代码的地方,每个方法调用一一个栈帧( 局部变量、this引用)
JVM调整参数
调整堆内存大小:-Xms256M –Xmx512M
调整栈内存大小:-Xss2048k
调整方法区大小:-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=128M
调整方法区大小:-XX:PermSize=64M –XX:MaxPermSize=128M Java 7及以前适用
2.GC怎么发现垃圾?
2.1.引用计数法(无法发现相互引用的垃圾对象)
2.2.根搜索算法
3.GC怎么回收(清理)垃圾?
3.1.标记清除(简单),缺点是内存碎片,使用效率不高
3.2.分段复制法,用一半,留一半,缺点:动静太大
3.3.标记-整理算法
3.4.分代收集
伊甸园(最新对象)、生存区(From、 To区)、老年代、永久代(方法区)
4.高效代码的技巧、避免内存泄漏
5.干掉JVM
堆内存溢出: -Xms -Xmx调整 堆内存大小
OutofMemoryError: Heap space堆 内存溢出错误
方法区溢出: -XX:MetaspaceSize -XX :MaxMetaSpaceSize 调整方法区大小
OutofMemoryError: Metaspace方法区内存溢出
栈内存溢出: -Xss调 整栈内存大小
StackoverflowError:栈内存溢出