JVM初步认识(一)

一.内存结构

1. jvm 的内存结构

在这里插入图片描述

a.栈:线程私有的(每个线程都有自己的栈内存,生命周期与线程相同)

  • 程序计数器(Program Counter Register):记录当前线程所执行的字节码的信号指示器
  • 本地方法栈(Native Method Stacks):非 Java 语言编写的方法(Native 方法)执行时需要的栈内存
  • 栈帧(Stack Frame):有多个,每个栈帧对应一次方法的调用,用来存储局部变量表、方法参数、操作栈、动态链接、方法出口等信息。
  • 每一个方法被调用到执行完成的过程,对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

b.堆:线程共享的(在虚拟机启动时就创建,需要注意线程安全问题)

  • 堆是 Java 虚拟机所管理的内存中最大的一块;

  • 新创建的对象实例、数组都存放在堆内存中;

  • Java 7开始,串池也会使用堆内存(之前串池用的是方法区内存),为什么会发生这样的变化呢?
    因为系统内字符串占用很大的空间,而方法区几乎不进行垃圾回收,方法区内存就会很容易出现内存溢出问题

  • 堆内存有垃圾回收处理机制,可以将堆内存分为新生代(伊甸园、2个幸存区)和老年代
    可以自己设置初始堆内存大小,最大堆内存,新生代堆内存,幸存区比例,TLAB内存 。

TLAB:新生代的一块特殊的部分,大小约为整个新生代的1%,每个线程可以在新生代中申请一块内存(tlab),使得此线程变为私有的,其他线程不能访问。在tlab中创建新的对象时,不需要加锁,这样就可以提升对象创建的效率。

c.方法区:线程共享的(Java 7实现叫做永久代)

  • 类版本、字段定义、方法定义;
  • 静态变量:Java 7 开始,使用了堆内存;
  • 常量池:串池从Java 7 开始,使用了堆内存。
  • 即时编译器(JIT)生成的代码:

即时编译器是一个把Java的字节码(包括需要被解释的指令的程序)转换成可以直接发送给处理器(processor)的指令的程序。
Java优点之一就是你只需要写和编译一次程序。在任何平台上,Java都会将编译好的字节码解释成能被特定的处理器所理解的指令(即一次编译,到处运行)。但尽管如此,Java虚拟机一次只能处理一条字节码指令。在特定的系统平台上使用Java即时编译器,能把字节码编译成特定系统的代码(虽然这个程序最初已经在这个平台上被编译过)。
一旦代码被JIT编译器(重)编译后,它在电脑上通常就会运行地更快。

2.非虚拟机内存(非堆内存)

Java 8 以后,移除了永久代,换为了元空间(meta space)
例如整个机器有8g的内存,jvm占用了500m,其他程序占用了 500m,呢么剩下的7g的内存都可以被元空间使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值