Java内存结构

JVM线程结构

Java内存结构_第1张图片

程序计数器:

一小块的内存区域,可以看做是当前线程执行字节码的行号指示器,为了确保线程切换之后恢复到上次执行的位置,每一个线程必须有一个独立的程序计数器。是线程的私有内存,是JVM中唯一没有规定任何内存溢出的内存区域。

JVM栈

虚拟机栈,线程私有,生命周期和线程相同。每个方法被调用是都会创建一个帧栈,用于存放局部变量,操作数栈,方法出口和动态链接等。局部变量空间是在编译器确定的。两种异常:如果单线程请求的栈深度大于虚拟机允许的最大深度,stackOverflowException,如果虚拟机栈可以动态扩展,当扩展到没有空间时,会抛出outOfMemoryException.

本地方法栈

JVM栈时虚拟机调用java方法服务,本地方法栈是为虚拟机调用操作系统服务。

虚拟机管理最大内存,被所有线程共享数据,虚拟机启动时创建,为了存放对象的实例。

方法区

方法区和堆一样所有线程数据共享,存放已被虚拟机加载的类变量,常量,静态变量。即编译过的数据。方法区最重要的是运行时常量池,用于存放编译期生成的字面变量,符号引用,直接引用。这些数据在类加载后存放于方法区的常量池中,运行时期也可以将新的常量放入常量池

 

JVM垃圾回收机制

jvm堆和非堆分为年轻代,年老代,永久代三种。年轻代和年老代就是共享堆,年轻代主要是动态的存储,存储新产生的对象,年老代存储年龄大些的对象。永久代就是方法区,主要存储java类信息,包括解析到的方法,字段,属性等。永久代基本不参与垃圾回收,我们所说的垃圾回收主要针对年轻代和年老代。

Java内存结构_第2张图片

年轻代又分为三个区域,eden,和两个sourvior,分成这三个部分主要是为了将生命周期短的留在年轻代。当eden空间不足时,会进行minorGC,存活对象放在sourvior。

年老代主要存放存活时间长的对象,比如缓存对象。

JVM垃圾回收过程

  • 对象在eden申请空间
  • 当eden区满了,创建对象,申请不到空间,会进行minorGC,对eden+sourvior区进行回收。
  • minorGC时,eden区不能被回收的数据会被放入sourvior,另外一个sourvior区不能被回收的对象也会被放入这个sourvior中,始终保持一个sourvior区域为空。
  • 当发现sourvior区域满了之后,会将sourvior中的对象移入老年代,或者在未满时将年龄足够的对象放入老生代。
  • old区满之后,进行fullGC.

minorGC,majorGC,fullGC

  • minorGC一般发生在年轻代,比较频繁,回收速度也快。
  • majorGC老年代垃圾回收,伴随着minorGC,速度比minorGC慢十倍左右。
  • fullGC整个堆进行垃圾回收,一般是majorGC。
  • majorGC和fullGC耗内存,所以要设置好年轻代和老生代的大小,当fullGC频繁的时候,内存也就接近溢出了。

JVM垃圾回收中的对象分配原则

  • 对象优先分配到eden区域,当eden区域不足时,进行minorGC回收。
  • 大对象直接放入老年代(占用连续内存大的),避免在eden区和sourvior拷贝。
  • 长期存活的对象放入老生代,jvm提供了年龄的计算,每经过一次minorGC未被回收的对象年龄就会加一,直到到达一个阈值后放入老生代。
  • 动态判断,如果sourvior中相同年龄的对象所占用空间大于等于sourvior的一半,那么年龄大于这些对象的将被放入老生代。
  • 空间分配担保,每次进行minorGC时,会计算需要移入老生代数据的大小和老生代剩余空间大小,如果后者小于前者,会进行fullGC,如果小于检查HandlePromotionFailure,true会进行minorGC,false进行fullGC。

jvm回收机制

  • 串行收集器:使用单线程,无需多线程交互,因此效率较高。
  • 并行收集器:使用多线程对年老代进行垃圾回收,因此可以减少回收时间,一般在多核多线程机器使用。
  • 并发收集器:可以并发收集,应用不停止,垃圾回收只占用较少的时间,适用于响应要求高,大规模应用。

常见内存溢出三种状况

堆溢出

head是年轻代和老生代大小之和,如果head中80%时间永远GC并且可用空间不足2%,会引发堆溢出。

解决办法:手动设置Head大小

PermGen溢出

永久代。存放class和meta,当加载过多的class会发生PermGen溢出溢出。

解决办法:设置-XX:permSize和-XX:permSizeMax大小即可

栈溢出

函数调用过程体现在了堆栈和退栈上,因此函数调用层越多,越容易发生栈溢出。

解决办法:设置-XSs

JVM常用参数

Java内存结构_第3张图片

你可能感兴趣的:(JAVA并发编程从入门到精通,Java内存结构)