JVM内存结构理解

JVM内存结构和JMM是两个东西,JVM内存结构指的是JVM的架构,而JMM只是的Java内存模型,这个是用来保证多个线程之间信息交换和数据同步用的。(PS:提一句,JMM是为了保证数据安全性定义的一组规范,最重要的是其中的happen-before法则,它的底层是通过内存屏障(memory barrier)禁止重排序来实现的)

 

JVM内存结构如下:

JVM内存结构理解_第1张图片

主要包括了下面几个部分:

  1. 程序计数器(线程私有

存放着当前线程所执行的字节码的行号指示器

  1. 栈(线程私有

每个方法被执行的时候都会创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息,每一个方法被调用直到执行完的过程就对应了一个栈帧在JVM中从入栈到出栈的过程。

  1. 本地方法栈(线程私有

与上面的栈相似,不同的是它是为执行native方法用的

  1. 方法区(永久代,对应JDK1.8中元空间,线程共享

存放JVM加载的类信息、常量,静态变量,即编译器编译后的代码等数据

  1. 堆(线程共享

JVM中内存最大的一块区域,在JVM启动的时候创建,用于存放几乎是所有对象的实例

 

GC算法针对的是堆:

JVM中的垃圾收集器回收的对象主要就是堆中的部分,因为每一个栈帧分配多少内存在类结构确定的情况下就是已知的,所以内存分配和回收比较容易。而方法区中的部分回收的性价比比较低,因为这一区域存放的都是一些常量以及类信息,经常会被用到,所以在JDK8中把这部分迁移到了本地内存来做。

而堆就不同,堆存放的是一些对象实例,很多都是一些朝生夕死的对象,一次回收就能回收大部分的空间,所以GC回收算法针对的主要是堆区域。

 

JVM堆大小相关的一些配置:

堆 = 年轻代 + 老年代,Sun官方建议年轻代大小为整个堆的3/8左右

JVM内存结构理解_第2张图片

    -Xmx: 最大堆内存

    -Xms: 初始堆内存大小,一般设置成和-Xmx一样,防止堆空间收缩引起额外的性能损耗

    -Xss:每个线程的栈大小

 

JVM调优的一些见解:

    1.GC调优的目的只有一个,尽量让对象在年轻代就回收掉,不要让它进入老年代

    2.大的年轻代会增加每次minor GC的时间,但是会延长GC的周期,而且大的年轻代说明老年代相对较小,会导致更频繁的Full GC

    3.通过参数设置GC调优一般是最后的手段,多数GC的问题一般都是代码的问题,应该首先考虑优化自己的代码

 

参考:

    http://www.cnblogs.com/ityouknow/p/5610232.html(参数控制各区域的内存大小)

你可能感兴趣的:(JVM)