【JVM读书笔记】- Java内存区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存分为若干个区域。

1. 程序计数器
  • 作用:通过改变这个计数器的值来选取下一条需要执行的指令。
    • 如果正在执行的是Java方法,那么计数器记录的是正在执行的虚拟机字节码指令地址;如果正在执行的是Native方法,那么此计数器为空。
  • 存储方式:由于Java虚拟机是通过线程轮流切换并分配处理器的方式来实现的,在任何一个确定的时刻,一个处理器(内核)都会执行一个线程中的指令。每个线程都有自己独立的程序计数器,各个线程之间计数器互不影响,独立存储。
2. Java虚拟机栈
  • 作用:每个方法在执行的同时会创建一个栈帧,用于存放局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用到执行完成,就对应着一个栈帧从入栈到出栈的过程。线程私有
  • 异常:如果线程请求的栈深度大于虚拟机允许的深度,将抛出stackOverFlowError异常;如果虚拟机栈允许动态扩展,如果扩展时无法申请到足够的内存,就抛outofMemoryError异常
3. Java堆
  • 作用:是所有线程共享的一块区域,在虚拟机启动时创建,此内存区域的唯一目的是存放对象的实例,所有对象实例以及数组都要在堆上分配。
  • 组成:
    • 新生代
      • Eden
      • Survivor0
      • Survivor1
    • 老年代
  • 异常:如果堆中没有内存完成实例分配,并且堆无法再扩展,将会抛出OutOfMemoryError
4. 方法区
  • 作用:各个线程共享,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
5. 运行时常量池
  • 作用:用于存储编译期生存的各种字面量和符号引用,这些常量是Class文件中的一部分。

看了一个项目beta环境的jvm内存空间,试用了一下jmap

ps aux | grep java
nobody   23580  7.9 30.1 4905964 1145092 ?     Sl   17:42   1:34 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server -Djava.awt.headless=true 
-Xms2048m -Xmx2048m -Xss256k 
-XX:PermSize=128m -XX:MaxPermSize=384m 
-XX:NewSize=1024m -XX:MaxNewSize=1024m 
-XX:SurvivorRatio=22 
-XX:+UseParNewGC -XX:ParallelGCThreads=4 -XX:MaxTenuringThreshold=9 -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+ScavengeBeforeFullGC -XX:+UseCMSCompactAtFullCollection -XX:+CMSParallelRemarkEnabled -XX:CMSFullGCsBeforeCompaction=9 -XX:CMSInitiatingOccupancyFraction=60 -XX:+CMSClassUnloadingEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:-ReduceInitialCardMarks -XX:+CMSPermGenSweepingEnabled -XX:CMSInitiatingPermOccupancyFraction=70 -XX:+ExplicitGCInvokesConcurrent -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=%CATALINA_HOME%conflogging.properties -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationConcurrentTime -XX:+PrintHeapAtGC -Xloggc:/data/applogs/heap_trace.txt -XX:-HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/applogs/HeapDumpOnOutOfMemoryError -Dcom.sun.management.snmp.port=9998 -Dcom.sun.management.snmp.interface=localhost -Duser.timezone=Asia/Shanghai -Dclient.encoding.override=UTF-8 -Dfile.encoding=UTF-8 -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n -Djava.endorsed.dirs=/usr/local/tomcat/endorsed -classpath /usr/local/tomcat/bin/bootstrap.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start
[betauser@vm_225-176 bin]$ sudo /usr/local/jdk/bin/jmap -heap 23580   # 查看整个JVM内存状态
Attaching to process ID 23580, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.80-b11

using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC

Heap Configuration:
   MinHeapFreeRatio = 40   #  GC后,如果发现空闲堆内存占到整个预估堆内存的40%,则放大堆内存的预估最大值,但不超过固定最大值
   MaxHeapFreeRatio = 70   #  GC后,如果发现空闲堆内存占到整个预估堆内存的70%,则收缩堆内存预估最大值。
   MaxHeapSize      = 2147483648 (2048.0MB)  #最大堆内存
   NewSize          = 1073741824 (1024.0MB)  #设置年轻代大小
   MaxNewSize       = 1073741824 (1024.0MB)  #设置年轻代最大值
   OldSize          = 5439488 (5.1875MB)     #设置老年代大小 ???
   NewRatio         = 2                      # 年老代/年轻代 = 2 即年轻代占堆内存的1/3  *** 使用了UseConcMarkSweepGC垃圾回收器后,此配置失效。
   SurvivorRatio    = 22                     #eden大小/survivor大小,即eden = 22/24, survivor=1/24 *2
   PermSize         = 134217728 (128.0MB)    #持久代大小
   MaxPermSize      = 402653184 (384.0MB)    #持久代大小最大值
   G1HeapRegionSize = 0 (0.0MB)              #使用默认的G1 GC垃圾回收器时,设置G1区域的大小

根据上面的描述,可知 持久代128MB, 年老代 512MB(???), 年轻代为1024MB, eden区:1024 * (22/24)= 938.66MB, survivor区: 42.66MB
Heap Usage:
New Generation (Eden + 1 Survivor Space):    #新生代: 938+42 = 981
   capacity = 1029046272 (981.375MB)
   used     = 792923344 (756.1906280517578MB)
   free     = 236122928 (225.1843719482422MB)
   77.05419722855767% used
Eden Space:       
   capacity = 984350720 (938.75MB)
   used     = 748227800 (713.5656356811523MB)
   free     = 236122920 (225.18436431884766MB)
   76.01231804859147% used
From Space:
   capacity = 44695552 (42.625MB)
   used     = 44695544 (42.62499237060547MB)
   free     = 8 (7.62939453125E-6MB)
   99.9999821011272% used
To Space:                                    # 看起来 survivor2区并没有算在新生代里
   capacity = 44695552 (42.625MB)
   used     = 0 (0.0MB)
   free     = 44695552 (42.625MB)
   0.0% used
concurrent mark-sweep generation:            # 老生代使用情况情况
   capacity = 1073741824 (1024.0MB)          
   used     = 4679768 (4.462974548339844MB)
   free     = 1069062056 (1019.5370254516602MB)
   0.43583735823631287% used
Perm Generation:                             # 永久代使用情况(永久代不在堆上)
   capacity = 134217728 (128.0MB)
   used     = 71334928 (68.03028869628906MB)
   free     = 62882800 (59.96971130371094MB)
   53.14866304397583% used

23875 interned Strings occupying 2709232 bytes.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值