Java 虚拟机内存模型

一、JVM组成:

程序计数器虚拟机栈本地方法栈
Java堆Java堆方法区

1、程序计数器:每一个线程有一个独立的程序计数器,用于记录下一条要运行的指令。各个线程之间的计数器互不影响,独立工作,是一块线程私有的内存空间。如果当前线程正在执行一个Java 方法,程序计数器记录正在执行的 Java 字节码地址。如果当前线程正在执行一个Native 方法,则程序计数器为空。

2、Java 虚拟机栈: 也是线程私有的内存空间,它和Java线程在同一时间创建,它保存方法的局部变量,部分结果,并参与方法的调用和返回。

    Java虚拟机规范允许Java栈的大小时动态或者是固定的。

   -Xss 参数设置栈的大小。
    在栈帧中,与性能调优关系最为密切的部分是局部变量表。
    
    jclasslib 工具
可以查看class文件中每个方法所分配的最大局部变量表的容量。

   下载地址: https://github.com/ingokegel/jclasslib

   2.1 局部变量表: 局部变量表以“字”为单位进行内存的划分,一个字为32位长度,long和 double型的变量占用2个字,
    其余类型使用一个字。问题: 一个long 数组占多少个字? 
     表中的变量可以重用相互的内存空间。有利于gc 时的内存回收。

    方法一结束,该方法的栈帧就会被销毁,栈帧中的局部变量表也被销毁,

3、本地方法栈:

4、Java 堆:

新生代

Edens0 (from space)s1 (to space)

老年代

4.1新生代:用于存放刚产生的对象年轻的对象。如果对象一直没有被回收,生存的足够长,老年对象就会被移入老年代。

 eden: 伊甸园。对象的出生地,大部分对象刚刚建立时,通常会放在这里。

s0和s1: survivor空间,幸存者,存放在其中的对象至少经历了一次垃圾回收。并得以幸存。如果幸存去的对象到了指定年龄仍未被回收,则有机会进入老年代(tenured)。

5、方法区: 也是JVM内存区中非常重要的一块内存区域。与堆内存类似。它也是被JVM中所有的线程共享的。它保存的信息是类的元数据。类的类型信息、常量池、域信息、方法信息。

   类型信息: 类的完整名称、父类的完整名称、类型修饰符(public、protected、private)、类型的直接接口和域修饰符。

  方法信息: 方法名称、返回类型、方法参数、方法修饰符、方法字节码、操作数栈、方法帧栈的局部变量区大小以及异常表。

 

   方法区也称为永久区,是一块独立于Java 堆的内存空间,虽然叫永久区,但永久区中的对象,同样也是可以被GC回收的。只是对于GC的表现也和Java 堆空间略有不同。对永久区GC的回收,通常主要从两个方面分析:一是GC对永久区常量池的回收;二是永久区对类元数据的回收。

  类的信息也会被回收,条件至少有:所有该类的实例被回收,且装载该类的 ClassLoader被回收。

6、JVM 内存分配参数

6.1 -Xmx 最大堆,指新生代和老年代的大小之和的最大值,是java 应用程序的堆上限。

   Runtime.getRuntime().maxMemory(): 取得系统可用的最大堆内存。

6.2 -Xms最小堆空间:JVM 启动时,所占据的操作系统内存大小。

    把 -Xms 的值设置为 -Xmx 时,可以在系统运行初期减少GC的次数和耗时。 

6.3 -Xmn 设置新生代的大小:设置一个较大的新生代会减少老年代的大小。这个参数对系统性能以及GC行为有很大的影响。

  新生代的大小一般设置为整个堆空间的 1/4到 1/3左右。

6.4  持久代(方法区):不属于堆的一部分。-XX:MaxPermSize 设置持久代的最大值,-XX:PermSize 可以设置持久代的初始大小。持久代的大小直接决定了系统可以支持多少类定义和多少常量。对于使用CGLIB或者 Javassist 等动态字节码生成工具的应用程序而言,设置合理的持久代大小有助于维持系统稳定。64M或128M 应该可以满足绝大部分应用程序正常工作,如果扔不能满足,则考虑优化系统设计。减少动态类的产生。

6.5 设置线程栈:线程栈是线程的一块私有空间, -Xss 设置线程栈的大小。在线程中进行局部变量分配,函数调用时,都需要在栈中开辟空间。如果栈的空间分配太小,会导致程序异常退出;如果栈空间过大,开设线程所需的内存成本就上升,系统所能支持的线程总数会下降。

如果系统确认书需要大量线程并发执行,那么设置一个较小的堆和较小的栈有助于提高系统所能承受的最大线程数。

6.6 堆的比例分配:-XX:SurvivorRatio 用来设置新生代中,eden空间和 s0空间的比例关系。 s0和s1分别称为 from 空间和 to 空间,它们的大小时相同的,职能也是一样的。并且在 Minor GC 后,会互换角色。

  -XX:SurvivorRatio=eden/s0=eden/s1

  -XX:NewRatio=老年代/新生代, 可以设置新生代和老年代的比例。

  -XX:+PrintGCDetiails: 打印堆的实际大小。

7、参数总结:

堆分配参数总结
参数说明
-Xms设置Java应用程序启动时的初始堆大小。
-Xmx设置Java应用程序能获得的最大堆大小。
-Xss设置线程栈的大小。
-XX:MinHeapFreeRatio设置堆空间最小空闲比例。当堆空间的空闲内存小于这个数值时,JVM便会扩展堆空间。
-XX:MaxHeapFreeRatio设置堆空间最大空闲比例。当堆空间的空闲内存大于该数值时,便会压缩空间,得到一个较小的堆。
-XX:NewSize设置新生代的大小。
-XX:NewRatio设置老年代与新生代的比例。它等于老年代大小除以新生带的大小。
-XX:SurviorRatio新生代中的 eden 区与 survivior区的比例。
-XX:MaxPermSize设置最大的持久区大小
XX:PermSize设置永久区的初始值
XX:TargetSurviorRatio

设置 survivior 区的可使用率。当 surviviorr 区的空间使用率达到这个数值时,会将对象送入老年代。      

                                                                                            NewRatio=m/l
                                                                        m                                                               l

                                               |---------------------------------|-------------------------------------------------------|

                                                                                                |------------------------- NewSize ------------------|

持久区老年代edens0s1
|------ PermSize -------- --------|                                                  |------------- n -----------|------ l ---------|
                                                                                                                   SurvivorRatio=n/l
                                                  |----------------------------------|---------------------------- --------------------------------|
                                                             老年代                                                                新生代

                                                   |--------------------------------- 堆 ----------------------------------------------|

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值