java运行时数据区::
程序计数器---------线程私有
java虚拟机栈-------线程私有
本地方法栈---------线程私有
java堆-------------线程公用
方法区-------------线程公用
jvm内存分配
栈内存分配:(私有的,不会存在线程安全)
- 保存参数,局部变量,中间计算过程和其他的数据,退出方法时候,修改栈顶指针就可以把栈中的内容销毁
-栈的优点:存取速度比堆快,仅次于寄存器,栈数据可以共享
-栈的缺点:存在栈中的数据大小,生存周期是在编译时就确定的,导致其缺乏灵活性
-xss: 每个线程最大数
堆内存的分配
- 堆的优点:动态地分配内存大小,生存期不必事先告诉编译器,它是在运行期动态分配的,垃圾回收器会自动收走不再使用的空间区域
- 堆的缺点:运行时动态分配内存,在分配和销毁时都要占用时间,因此效率较低
jvm堆结构:young old permantent
Young 新生区
- Eden(E区):舒适区 ->new object 优先放置
- SurvivorSpaces(S区):挽救区-->一次回收
From(s0)
To(s1)
- Old(Tenured Generation) :老的-->二次回收
- Permanert:方法区
java堆结构和垃圾回收()
Direct Gen:java 1.7以上存在内存映射 可以直接操作物理内存,不会通过jvm(spring 反射)
java GC管理:
Perm Germ->minor GC->old ger==full gc
jvm堆配置参数
1.-Xms初始堆大小
默认物理内存的1/64(<1GB)
2.-Xmx最大堆大小
默认物理内存的1/4(<1GGB),实际中建议不大于4GB
3.一般建议设置 -Xms=-Xmx
好处是避免每次GC后,调整堆的大小,减少系内存的分配开销
4.整个堆的大小=年轻代大小+年老代大小+持久代大小
jvm新生代(young generation:-Xmn)
1.新生代=1个Eden区+2个Survisor区
2.-Xmn 年轻带大小(1.4 or lator)
-XX:NewSize,-XX:MaxNewSize(before 1.4)
默认整个堆的3/8
3.-XX:NewRatio
年轻带(eden and survivor)与年老带的比值(除去持久代)
Xms=Xmx并且设置了Xmm的情况下,该参数不需要设置
4.-XX:SurvivorRatio==>E+S1+S2~8/1/1
Eden区与Survivor区的大小比值大小,设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占年轻带的1/10
5.用来存放JVM刚分配的java对象优先放入young区
java老年代(tenured generation)
1.老年代=整个堆-年轻代大小-持久代大小
2.年轻代中经过垃圾回收没有回收掉的对象被复制到老年代
3.老年代存储对象比年轻代年龄大的多,而且不乏大对象
4.新生的对象也有可能直接进入老年代
4.1大对象可通过启动参数设置-XX:PreteureSizeThreshold=1024(单位为 字节,默认为零)来代表超过多大时就不在新生代分配,而是直接在老年代分配
4.2大的数组对象,且数组中无引用数组中无引用外部对象.
5.老年代无配置参数
java持久代(perm generation)
1.持久代=整个堆-年轻代-老年代大小
2.-XX:PermSize -XX:MaxPermSize
设置持久代的大小,一般情况推荐把-XX:PermSize设置成XX:MaxPermSize
的值,因为永久代大小的调整也会导致堆内存需要触发fgc.
3.存放Class\Method元信息,其大小与项目的规模\类\方法的常量有关.一般设置为 128M就足够,设置原则预留30%的空间.
4.永久代的回收方式
4.1常量池中的常量,无用的类信息,常量的回收很简单,没有引用就被回收了
4.2对于无用的类进行回收,必须保证三点:
类的所有实例都已经被回收
加载类的ClassLoader已经被回收
类对象的Class对象没有被引用(既没有被映射)
JVM垃圾回收算法
1.引用计数算法
每个对象都有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减 1,计数为0时可以回收.此方法简单,无法解决对象相互循环引用的问题.还有一 个问题是如何解决精准计数.(1.2之前)
2.根搜索算法
从GC ROOTS开始向下搜索,搜索所走过的路径称为引用链.当一个对象到GC ROOT没有任何引用链相连时,则证明此对象是不可用的,不可达对象.
在java语言中,GC ROOTS包括:
虚拟机栈中引用的对象
方法区中类静态属性实体引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
JVM垃圾回收算法
1.复制算法(Copying)
- 复制算法采用从根集合扫描,并将存活对象复制到一块新的,没有使用过的空 间,这种算法当空间存活的对象比较少时,极为高效,但是带来的成本需要一块 内存交换空间
- 此算法用于新生代内存回收,从E区回收到S0或S1区
2.标记清除算法(Mark-Sweep)
- 对引用的进行标记,对未标记的进行回收,无对象移动
3.标记整理压缩算法(Mark-Compac)
- 对引用的进行标记,对未标记的回收,有对象移动