1、先来了解一下Java虚拟机的体系统结构:

java虚拟机得内存结构 java虚拟机的内存模型_java虚拟机得内存结构

首先JVM通过类装载子系统将Java程序编译好的字节码装载并运行,JVM的运行时数据区包括方法、Java堆、Java栈、程序计数器和本地方法栈。其中的方法区和Java堆是共享内存,而Java栈、程序计数器和本地方法栈是属于线程栈,这一点从下面一幅中可以看出来,JVM运行时由执行引擎调用操作系统本地接口。

2、JVM运行时数区之间的关系图:

java虚拟机得内存结构 java虚拟机的内存模型_java虚拟机得内存结构_02

从上图中我们可以看到,Heap(堆)、Method Area(方法区)是多线程共享的内存,其中常量池在包含在方法区中。而PC Register(程序计数器)、JVM Stack(JVM栈)、Native Method Stack(本地方法栈)都是每个线程分配独立的内存。

3、Java虚似机内存模型的说明:

java虚拟机得内存结构 java虚拟机的内存模型_垃圾回收_03

java虚拟机得内存结构 java虚拟机的内存模型_java虚拟机的内存模型_04

从上面两张图中可以看出

Java内存是由共享内存区和线程内存区组成,即:

Java内存区 = 共享内存区 + 线程内存区。

共享内存区是由持久空间和Java堆组成,即:

共享内存区大小 = 持久空间大小(PermSize) + 堆空间大小(HeapSize)。

注:持久空间实现方法区,主要存放所有已知加载类的信息、方法信息和常量池等。

Java堆内存的大小又是由Old Space 和 Young Space组成的,即:

Heap(堆) =  Old Space + Young Space。

注:Java堆主要用于存放类对象的实例信息。

Young Space又是由Eden(存放新生对象的伊甸园)和S0和S1组成的,即:

Young Space = Eden + S0 + S1。

S0和S1是两个大小相同的内存区域,主要存放每次垃圾回收后Eden存活的对象,作为对象从Eden过渡到Old Space的缓冲地带(S是指英文单词Survivor Space)。

4、线程内存区:

java虚拟机得内存结构 java虚拟机的内存模型_java虚拟机得内存结构_05

线程内存区=单个线程内存+单个线程内存+.......

单个线程内存=PC Regster+JVM栈+本地方法栈

JVM栈=栈帧+栈帧+.....

栈帧=局域变量区+操作数区+帧数据区

在Java中,一个线程会对应一个JVM栈(JVM Stack),JVM栈里记录了线程的运行状态。

JVM栈以栈帧为单位组成,一个栈帧代表一个方法调用。栈帧由三部分组成:局部变量区、操作数栈、帧数据区。

5、JVM内存的设置:

-Xmx

Java Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定;-Xmx 此设置控制 Java 堆的最大大小。正确调整此参数有助于降低垃圾回收开销,从而缩短服务器响应时间并提高吞吐量。

对于某些应用程序来说,此选项的缺省设置可能会太低,从而导致发生大量小型垃圾回收。

缺省值: 512 MB

建议值: 随工作负载的不同而有所变化,但高于缺省值。

用法: -Xmx512m 将最大堆大小设置为 512 兆字节

-Xms

Java Heap初始值,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM可以保留默认值;设置堆大小 下列命令行参数对于设置堆大小来说很有用。 -Xms 此设置控制 Java 堆的初始大小。正确调整此参数有助于降低垃圾回收开销,从而缩短服务器响应时间并提高吞吐量。对于某些应用程序来说,此选项的缺省设置可能会太低,从而导致发生大量小型垃圾回收。

缺省值: 256 MB

建议值: 随工作负载的不同而有所变化,但高于缺省值。

用法: -Xms256m 将初始堆大小设置为 256 兆字节

-Xmn

Java Heap Young区大小,不熟悉最好保留默认值;-Xmn 此设置控制允许新生成的对象在堆中耗用的空间量。正确调整此参数有助于降低垃圾回收开销,从而缩短服务器响应时间并提高吞吐 量。此参数的缺省设置通常过低,这将导致执行大量的小型垃圾回收操作。如果将此参数设置得过高,可能会导致 JVM 仅执行大型( 全面)垃圾回收。这些垃圾回收操作通常会耗时几秒钟,这将严重影响服务器的整体性能。您必须保持将此参数设置为小于整个堆大 小的一半,以避免这种情况出现。

缺省值: 2228224 字节

建议值: 大约整个堆大小的 1/4

用法: -Xmn256m 将大小设置为 256 兆字节。

-Xss

每个线程的Stack大小,不熟悉最好保留默认值;