Java-理解Java虚拟机

本文是阅读《深入理解Java虚拟机》后的总结

一个很形象的比如 Java虚拟机有一堵围墙 外面的人想进来 里面的人要出去 对应了Java虚拟机的自动内存分配和垃圾回收机制


1.首先Java虚拟机的内存分区

堆:最大的一块 所有的对象实例以及数组都要在堆上分配内存 堆中会分新生代和老年代 

栈:分虚拟机栈和本地方法栈 对应的是Java的方法 每个方法执行的时候都是会分配一个栈存放着各种变量值 他们之间的差别 虚拟机栈是执行虚拟机的Java方法的栈 本地方法执行的是native方法  都outofmenory

方法区:都是线程私有 主要是一些常量信息 比如一些类信息 静态变量 

里面有运行时常量池 

程序计算器 主要负责记录程序运行到了哪里


2.什么时候会发生OutOfMemoryError

堆溢出:如果堆只有20M 然后我一直循环

while(true){

list.add(new Person);

}

栈溢出(虚拟机栈和本地方法栈溢出):

StackOverflowError :如果线程申请的栈深度大于虚拟机允许的栈的最大深度  递归的时候发生比较多 

OutofMemoryError: 如果在扩展栈时无法申请足够的内存空间

方法区和运行时常量池溢出:


3.下面正式进入主题了 那么Java虚拟机到底是怎么内存动态分配和垃圾回收的呢?

1)如何判断对象该回收:

引用计数法就不说了 因为它无法解决循环引用的问题 基本实践不会用到

可达性算法:就是有一些GC roots (比如虚拟机栈中的对象 方法区常量引用的对象 方法区中类静态属性引用的对象 反正就是一些对象)

如果那些对象和GC roots没有任何关联 那么就可以认为可以回收


2)卧槽 那引用到底是什么意思?

如果reference类型的数据中存储的数值代表的是另一块内存的起始地址 那么久称为一个引用

又分为强引用 软引用 弱引用 虚引用 


4.好了 垃圾确定了 那么到底具体怎么回收垃圾来了

1)标记清除算法:这个比较简单 效率也不高 碎片化严重 顾名思义 就是确定了垃圾 就直接删除这些垃圾

2)复制算法:就是将内存分为2块 只是使用其中的一块 需要清除的时候 就将那块存活的对象复制到还没使用的那一块 然后整块清除

3)标记-整理算法 复制算法不太适合老年代 所以提出了标记整理算法不是直接对对象进行回收 而是将所有存活的对象向一端移动然后直接清除掉边界以外的内存

4)现代虚拟机都是采用分代收集算法了 就是按照不同情况采用不同的清除算法呗


5)内存分配 

这个更简单 其实就是在堆中分配内存 我们知道 堆又分新生代和老年代

多数的对象在新生代Eden区分配 大对象直接进入老年代 长期存活的对象也将进入老年代





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值