Java Runtime Data Area

Java 内存模型

Java内存模型 不是JMM内存模型,这个是Java Runtime Data Area。
可以按照2个维度来划分,线程独占和非线程独占。

线程独占

  1. 本地方法栈
  2. 程序计数器

用来保存方法的局部变量

  1. 基本数据类型的值
  2. 保存方法执行的栈帧
  3. 保存对象的实例(指向堆的指针)

本地方法栈

用来支持虚拟机使用到的native方法服务
保存对方发的出入栈和入参地址和返回地址。
先入先出的结构。

程序计数器

用来记录线程执行的位置,当线程执行native方法的时候程序计数器为空。

  1. 为什么要有程序计数器

在Java的环境中,可能是多个线程执行的,根据系统调度的算法可能当前方法会挂起,
当前执行的线程会执行别的方法,所以需要一个记录执行位置的。

非线程独占

  1. 方法区(元数据区)

用来存放实例,对象实例都在这里分配。当堆内存没有可用的空间时,会抛出 OOM 异常。

堆内存的划分

Java内存空间划分

堆内存分为新生代和老年代

新生代

存放新创建的对象实例,当这个对象实例过大的时候会直接去老年代创建

新生代分区
生成区(伊甸园区或者eden区)
幸存者区(survivor)
幸存者区又分为FromSpace和ToSpace(s0或者s1区)

默认新生代内存比例是8:1:1

幸存者区为什么要采用两个相等的分区

新生代回收算法相关, 如果不是G1的回收算法,在1.8中默认使用的标记复制算法,使用一块内存,减少不连续空间碎片的生成

默认比例8:1:1失效的情况

如果新生代的回收器采用的是Parallel Scavenge,不修改参数比例的情况下可能会失效,Parallel Scavenge 会自适应内存情况来修改内存比例。

担保机制

不同的垃圾回收器不一样的这里优先说ParallelGC,

Java执行参数如下 -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseSerialGC

private static final int DEF_MB = 1024 * 1024;

    public static void testHandlePromotion() {
        byte[] allocation1, allocation2, allocation3, allocation4;
        allocation1 = new byte[2 * DEF_MB];
        allocation2 = new byte[2 * DEF_MB];
        allocation3 = new byte[2 * DEF_MB];
        allocation4 = new byte[4 * DEF_MB];
    }

    public static void main(String[] args) {
        testHandlePromotion();
    }

gc日志如下
/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/bin/java -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseSerialGC -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=56007:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/tools.jar:/Users/crazy/Desktop/code/JavaCode/target/classes:/Users/crazy/.m2/repository/org/springframework/spring-aop/4.3.8.RELEASE/spring-aop-4.3.8.RELEASE.jar:/Users/crazy/.m2/repository/org/springframework/spring-beans/4.3.8.RELEASE/spring-beans-4.3.8.RELEASE.jar:/Users/crazy/.m2/repository/org/springframework/spring-core/4.3.8.RELEASE/spring-core-4.3.8.RELEASE.jar:/Users/crazy/.m2/repository/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/Users/crazy/.m2/repository/org/springframework/boot/spring-boot-starter-aop/1.5.11.RELEASE/spring-boot-starter-aop-1.5.11.RELEASE.jar:/Users/crazy/.m2/repository/org/springframework/boot/spring-boot-starter/1.5.11.RELEASE/spring-boot-starter-1.5.11.RELEASE.jar:/Users/crazy/.m2/repository/org/springframework/boot/spring-boot-starter-logging/1.5.11.RELEASE/spring-boot-starter-logging-1.5.11.RELEASE.jar:/Users/crazy/.m2/repository/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar:/Users/crazy/.m2/repository/ch/qos/logback/logback-core/1.1.11/logback-core-1.1.11.jar:/Users/crazy/.m2/repository/org/slf4j/slf4j-api/1.7.22/slf4j-api-1.7.22.jar:/Users/crazy/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.25/jcl-over-slf4j-1.7.25.jar:/Users/crazy/.m2/repository/org/slf4j/jul-to-slf4j/1.7.25/jul-to-slf4j-1.7.25.jar:/Users/crazy/.m2/repository/org/slf4j/log4j-over-slf4j/1.7.25/log4j-over-slf4j-1.7.25.jar:/Users/crazy/.m2/repository/org/yaml/snakeyaml/1.17/snakeyaml-1.17.jar:/Users/crazy/.m2/repository/org/aspectj/aspectjweaver/1.8.13/aspectjweaver-1.8.13.jar:/Users/crazy/.m2/repository/cglib/cglib/2.1_3/cglib-2.1_3.jar:/Users/crazy/.m2/repository/asm/asm/1.5.3/asm-1.5.3.jar:/Users/crazy/.m2/repository/cglib/cglib-nodep/2.2/cglib-nodep-2.2.jar:/Users/crazy/.m2/repository/redis/clients/jedis/2.9.0/jedis-2.9.0.jar:/Users/crazy/.m2/repository/org/apache/commons/commons-pool2/2.4.2/commons-pool2-2.4.2.jar:/Users/crazy/.m2/repository/junit/junit/4.13/junit-4.13.jar:/Users/crazy/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Users/crazy/.m2/repository/mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47.jar:/Users/crazy/.m2/repository/org/apache/commons/commons-lang3/3.8/commons-lang3-3.8.jar:/Users/crazy/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar:/Users/crazy/.m2/repository/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar:/Users/crazy/.m2/repository/org/springframework/boot/spring-boot-devtools/1.5.17.RELEASE/spring-boot-devtools-1.5.17.RELEASE.jar:/Users/crazy/.m2/repository/org/springframework/boot/spring-boot/1.5.17.RELEASE/spring-boot-1.5.17.RELEASE.jar:/Users/crazy/.m2/repository/org/springframework/spring-context/4.3.20.RELEASE/spring-context-4.3.20.RELEASE.jar:/Users/crazy/.m2/repository/org/springframework/spring-expression/4.3.20.RELEASE/spring-expression-4.3.20.RELEASE.jar:/Users/crazy/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.5.17.RELEASE/spring-boot-autoconfigure-1.5.17.RELEASE.jar:/Users/crazy/.m2/repository/org/projectlombok/lombok/1.16.14/lombok-1.16.14.jar:/Users/crazy/.m2/repository/io/netty/netty-all/4.1.39.Final/netty-all-4.1.39.Final.jar:/Users/crazy/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar:/Users/crazy/Downloads/mysql-binlog-connector-java-0.21.0.jar com.jvm.gc.TestHandlePromotionFailure
[GC (Allocation Failure) [DefNew: 6465K->569K(9216K), 0.0037041 secs] 6465K->4665K(19456K), 0.0037317 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
 def new generation   total 9216K, used 7035K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  eden space 8192K,  78% used [0x00000007bec00000, 0x00000007bf250710, 0x00000007bf400000)
  from space 1024K,  55% used [0x00000007bf500000, 0x00000007bf58e538, 0x00000007bf600000)
  to   space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
 tenured generation   total 10240K, used 4096K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
   the space 10240K,  40% used [0x00000007bf600000, 0x00000007bfa00020, 0x00000007bfa00200, 0x00000007c0000000)
 Metaspace       used 3041K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 329K, capacity 388K, committed 512K, reserved 1048576K

这里在GC前会进行一次判断,如果分配的内存大于等于eden区大小的一半,那么会直接把要分配的内存放在老年代中,否则才会进入担保机制。

方法区(元数据区)

用于存放已被虚拟机加载的类信息、常量、静态变量,即编译器编译后的代码。

为什么要干掉方法区换成元数据区

因为随着动态加载类的越来越多,方法区越来越不可控,内存大了可能浪费,小了可能出问题。

方法区的划分
Klass(元数据指针)

class文件在jvm里运行期间的数据结构
每个Java对象的对象头里,都会有一个_klass字段,
会指向vm内部用来记录类的元数据的实例对象(InstanceKlass)

NoKlass

用来存放其klass的其他内容,比如方法,常量池,可以有多个不连续的内存款组成

方法区的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>