JVM学习(一)_概述
一,为什么要学JVM内存
java程序无需显示分配和回收内存,由jvm自动管理内存的分配及回收,给开发人员降低了编写程序的难度,
副作用是可能在不知不觉中浪费了很多内存, 导致jvm花费很多时间进行内存回收, 另外由于不清楚jvm内存的分配和回收机制, 有可能造成内存泄露.
因此jvm如何进行内存的分配和回收也是要关注的问题.
二, JVM内存的结构
Jvm将内存空间划分为方法区, 堆 ,本地方法栈, PC寄存器 和jvm方法栈.
JVM标准结构
JVM内存结构
三,分析各个区域
3.1 方法区
方法区又叫持久带(Permanent Generation). 默认最小16M, 最大64M, 超过最大时会抛出OutOfMemory异常, 可通过
-XX:PermSize 及 –XX:MaxPermSize来指定最小值和最大值.
方法区存放哪些东西?
加载的类的信息(名称,修饰符等), 字段的信息, 方法的信息, 静态变量, final的常量.
方法区是全局共享的, 一定条件下也会被GC.
3.2 堆
堆是干嘛的?
用来存储对象实例及数组值
堆有多大空间?
默认最小为物理内存的1/64但小于1G, 最大为物理内存的1/4但小于1G, 可以用-Xms和-Xmx来调节最大和最小值,不过在32位系统上最大为2G,在64位系统上没有最大值限制.
什么时候堆的空间达最大?什么时候达最小?
默认当剩余空间小于40%时JVM会将堆增大到-Xmx指定的大小,当剩余空间大于70%时JVM会将其减小到-Xms指定的大小,这个比例也可以自己设置,
通过-XX:MinHeapFreeRatio和-XX:MaxHeapFreeRatio指定最大和最小比例.
对运行系统而言,为避免JVM频繁调整堆大小,通常将-Xms和-Xmx设为一样.
JDK1.2后堆分为新生代(new Generation)和旧生代(old Generation)两部分.
新生代 = Eden Space + 2个相同大小的Survivor space(通常称S0和S1或from和to)
大多数情况下新建的对象都在新生代中
旧生代干什么的?
用来存放经过多次垃圾回收但仍然存活的对象, 存放没有引用外部对象的大数组对象,
存放超过-XX:PretenureSizeThreshold=100(单位为字节,默认0)指定的字节数的对象,这个参数就是说如果某个对象超过
100字节就不放在新生代中,直接放在旧生代中
当堆上空间不足时会触发GC, 如果GC后空间仍然不足则抛出OutOfMemory
3.3 本地方法栈
支持带有native修饰的方法执行, 比如说Thread类中就有
private static native void registerNatives();
public static native Thread currentThread();等native方法
SUN JDK的实现中本地方法栈和JVM方法栈是同一个
3.4 jvm方法栈
JVM方法栈是干嘛的?
按照”本地方法栈”的解释,我自己理解就是支持非native的方法执行.
每个线程都会创建JVM方法栈,是每个线程私有的,当方法运行完,其对应的内存也会自动释放.jVM方法栈空间不足时抛出StackOverFlowError错误
3.5 PC寄存器
PC寄存器是干嘛的?
不知道,不过每个线程都会创建PC寄存器
参考链接:
http://www.cnblogs.com/redcreen/archive/2011/05/04/2036387.html
http://aub.iteye.com/category/279337
http://java.chinaitlab.com/Special/JVM/index.html