JVM学习笔记5:内存分配

一:jvm的内存简化架构

 

二:运行时数据区

    Java虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机的退出而销毁。另外一些则是与线程一一对应的,这些与线程对应的数据区域会随着线程的开始和结束而创建和销毁。其分为pc寄存器(程序计数器)java虚拟机栈Java堆方法区运行常量池本地方法栈
 

  1. PC(Program Counter)寄存器:
    a.Java虚拟机可以支持多条线程同时执行,每一条Java虚拟机线程都有自己的pc寄存器。
    b.在任意时刻,一条java虚拟机线程只会执行一个方法的代码,这个正在被线程执行的方法称为该线程的当前方法。
    c.如果当前方法不是native的,pc寄存器保存java虚拟机正在执行的字节码指令的地址。
    d.如果当前方法是native的,pc寄存器的值是undefined
  2. Java虚拟机栈:
    a.栈由一系列帧(Frame)组成(因此Java栈也叫做帧栈),是线程私有的
    b.帧用来保存一个方法的局部变量、操作数栈( Java没有寄存器,所有参数传递使用操作数栈)、常量池
          指针、动态链接、方法返回值等
    c.每一次方法调用创建一个帧,并压栈,退出方法的时候,修改栈顶指针就可以把栈帧中的内容销毁
    d.局部变量表存放了编译期可知的各种基本数据类型和引用类型,每个slot存放32位的数据,long、
         double占两个槽位
    e.栈的优点:存取速度比堆快,仅次于寄存器
    e.栈的缺点:存在栈中的数据大小、生存期是在编译期决定的,缺乏灵活性
     
  3. Java堆:
    a.用来存放应用系统创建的对象和数组,所有线程共享Java堆
    b.GC主要就管理堆空间,对分代GC来说,堆也是分代的
    c.堆的优点:运行期动态分配内存大小,自动进行垃圾回收
    d.堆的缺点:效率相对较慢
  4. 方法区:
    a.方法区是线程共享的,通常用来保存装载的类的结构信息,比如:
          运行时常量池字段,方法数据、方法字节码在类、实例、接口初始化用到的特殊方法
    b.通常和永久区关联在一起,但具体的跟JVM的实现和版本有关,比如JDK7就把String从方法区移到堆了,JDK8直接去掉          永久区,取而代之的是元空间。
    c.JVM规范把方法区描述为堆的一个逻辑部分,但它有一个别名称为Non-heap(非堆),应该是为了与Java堆区分开
  5. 运行常量池:
    a.是Class文件中每个类或接口的常量池表在运行期间的表示形式,通常段、方法、接口等信息
    b.在方法区中分配
    c.通常在加载类和接口到JVM后,就创建相应的运行时常量池
  6. 本地方法栈
     在JVM中用来支持native方法执行的栈就是本地方法栈。

三:堆的结构

 

 

1:整个堆大小 = 新生代+老年代
2:新生代 = 1个eden区 + 2个survivor区,新生代用来放刚分配的对象
3:老年代=整个堆-新生代,新生中经过垃圾回收, 没有回收掉的对象,被复制到老年代。老
年代存储对象比新生年龄大得多,包含一些大对象
4:从前的持久代,用来存放Class、Method等元信息的区域,在JDK8中已经没有了,取而代
之的是元空间(MetaSpace),元空间并不在虚拟机里面,而是直接使用本地内存。
 

Heap
 PSYoungGen      total 2048K, used 1169K [0x00000000ffd80000, 0x0000000100000000, 0x0000000100000000)
  eden space 1536K, 76% used [0x00000000ffd80000,0x00000000ffea4738,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
  to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 ParOldGen       total 5632K, used 5616K [0x00000000ff800000, 0x00000000ffd80000, 0x00000000ffd80000)
  object space 5632K, 99% used [0x00000000ff800000,0x00000000ffd7c1a8,0x00000000ffd80000)
 Metaspace       used 3213K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 349K, capacity 388K, committed 512K, reserved 1048576K
  • PSYoungGen:新生代情况
  • PSOldGen:老年代情况,占用空间10240K,10M,这个是老年代的活跃数据情况
  • Metaspace:元空间。(JDK7 以前为PSPermGen:永久带情况)
  • Eden Space (heap): 内存最初从这个线程池分配给大部分对象。
  • Survivor Space (heap):用于保存在eden space内存池中经过垃圾回收后没有被回收的对象。
  • Tenured Generation (heap):用于保持已经在 survivor space内存池中存在了一段时间的对象。
  • Permanent Generation (non-heap): 保存虚拟机自己的静态(refective)数据,例如类(class)和方法(method)对象。Java虚拟机共享这些类数据。这个区域被分割为只读的和只写的,
  • Code Cache (non-heap):HotSpot Java虚拟机包括一个用于编译和保存本地代码(native code)的内存,叫做“代码缓存区”(code cache)

四:Jvm参数

  1. Trace跟踪参数
        a.可以打印GC的简要信息
                 -verbose:gc
                 -XX:+printGC
         b.打印GC详细信息
               -XX:+PrintGCDetails
         c.打印CG发生的时间戳
               -XX:+PrintGCTimeStamps
         d.指定GC log的位置,以文件输出
                -Xloggc:log/gc.log
         e.每一次GC后,都打印堆信息
              -XX:+PrintHeapAtGC
        f.监控类的加载
              -XX:+TraceClassLoading
        g.打印类的直方图
              -XX:+PrintClassHistogram
     按下Ctrl+Break后,打印类的信息:分别显示:序号、实例数量、总大小、类型
  2. Java堆的参数

              a.Xms:初始堆大小,默认物理内存的1/64(<1g)
              b.Xmx:最大堆大小,默认物理内存的1/4(<1G)
                    建议xms=xmx,好处是避免每次gc后,调整堆的大小,减少系统内存分配开销
              c.Xmn:新生代大小,默认整个堆的3/8
              d.-XX:NewRatio:新生与老年代的比值,不包含持久代
                        如果xms=xmx,且设置了xmn的情况下,该参数不需要设置
               e.-XX:SurvivorRatio:Eden区和Survivor区的大小比值,设置为8,则两个Survivor区与一
                         个Eden区的比值为2:8,一个Survivor占整个新生的1/10
              f.新建的对象也有可能直接进入老年代,比如:大对象,可通过设置-XX:PretenureSizeThreshold=1024(单位为字                                  节,默认为0)来代表超过多大时就不在新生代分配,而是直接在老年代分配
             g. -XX:+HeapDumpOnOutOfMemoryError:OOM时导出堆到文件
             h. -XX:+HeapDumpPath:导出OOM的路径
              i. -XX:OnOutOfMemoryError:在OOM时,执行一个脚本,例如:
                  -XX:OnOutOfMemoryError=D:/mytest.bat %p

推荐配置

  • 根据实际应用来调整新生代和幸存代的大
  • 官方推荐新生代占堆的3/8
  • 幸存代占新生代的1/10
  • 在OOM时,记得Dump出堆,确保可以排查现场问题

 

3.Java栈的参数

-Xss
通常只有几百K
决定了函数调用的深度
4.元空间的参数

a.-XX:MetaspaceSize初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值
b.-XX:MaxMetaspaceSize最大空间,默认是没有限制的
c.-XX:MinMetaspaceFreeRatio在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
e.-XX:MaxMetaspaceFreeRatio在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值