JAVA内存是自动管理的,如果我们不清楚内存的回收机制,容易造成内存泄露和内存不够用
内存总的来说分为 方法区和堆栈区
1、方法区
方法区就是放了要加载类的的信息、类中静态变量、类中定义的final类型的常量、filed信息以及方法信息。
在sun jdk中这个区域对应的是Permanet Generation,称作持久带,默认最小值16M,最大值64M,可以通过-XX:PermSize及 -XX:MaxPermSize来指定最小和最大值
2、堆
这个理论是可以定义任意大小。默认值的最小值-Xms是内存的1/64,最大不超过1G
默认值的最大值-Xmx是内存的1/4,最大不超过1G
不过在32位系统上最大就是2G
新创建的对象都在eden中,当超过一定的次数调用转移到旧生代中,S0/S1就是用来进行内存回收的时候进行数据存放的。当-Xms的剩余空间小于40%自动增长到Xmx的值,当Xmx有70%的空闲的时候自动的降低到-Xms的值,为了避免他的自动调整,最好将这两个设置成一样的值
3、sun jdk堆的分代
分为 新生代(eden,S0,S1),旧生代
其中S0,S1的大小相同
新生代中的eden的默认系数是8,如果设置新生代是10M,那么eden是8M,S0/S1一样大,各自是1M
可以直接设置对象大小值,直接进入旧生代。
4、本地方法栈,pc寄存器和jvm方法栈
当jvm方法栈内存不足的时候会出现stackoverflowerror
这个可以通过设置-Xss参数设置
5、内存回收
主要是跟踪收集器,可以分成 复制、标记清除、标记压缩 三种方式进行内存回收
6、sun jdk可用的gc
新生代可用 串行gc、并行回收gc、并行gc
旧生代可用 串行gc、并行Gc,并发Gc
7、调优相关
核心关注点就是吞吐量优先策略(可以通过-XX:GCTimeRatio=n设置新生代和旧生代大小)和暂停时间优先策略
常规情况下我们不需要调整相关的参数,只需要调整持久带和堆内存大小即可