JVM内存结构

文章详细介绍了JVM的内存结构,包括程序计数器的线程私有特性,虚拟机栈的栈帧概念和栈内存溢出,堆内存的线程共享和垃圾回收机制,本地方法栈的native方法处理,以及方法区的运行时常量池和内存溢出情况。还提到了如何进行线程运行诊断和内存诊断的工具使用。
摘要由CSDN通过智能技术生成

一、Program Counter Register程序计数器(寄存器)

作用:记住下一条JVM指令的地址

特点:

        线程私有,每个线程都有自己的程序计数器

        唯一一个不会存在内存溢出的

二、虚拟机栈(JVM Stacks, Java Virtual Machine Stacks)

1、定义及概念

        栈帧:每个方法运行时需要的内存,参数、局部变量、返回地址。

        每个线程运行时所需要的内存,称为虚拟机栈。

        每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存。

        每个线程只能有一个活动栈帧,对应着栈顶部那个当前正在执行的方法。

2、相关问题

垃圾回收是否涉及栈内存?

        不涉及,栈帧内存每次方法调用完之后,都会弹出栈会自动被回收掉。

栈内存分配越大越好吗?

        栈内存可以通个虚拟机的参数配置 -Xss,栈分配的内存越大,反而会让线程数变少。因为物理内存的大小是一定的,例如500M,如果每个线程划分2M,则最多可以运行250个线程,但如果每个线程划分1M,则最多可以运行500个线程。一般采用系统默认的栈内存。

方法内的局部变量是否线程安全?

        是线程安全的,局部变量是线程私有的,线程内每次方法调用都会产生一个栈。

        如果是static的变量,就会产生线程安全问题。如果是传入参数,或者是返回值,就有可能不是线程安全的。

        如果方法内局部变量没有逃离方法的作用范围,它就是线程安全的。

        如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全问题。

3、栈内存溢出(StackOverflowError)

        栈帧过多导致栈内存溢出:递归调用未写出合适的递归终止方法。

        栈帧过大导致栈内存溢出

4、线程运行诊断

        CPU占用过多:

                top命令查看进程编号

                ps -ef 查看线程类

                jstack进程id查看所有线程的运行情况,查看有问题的线程,查看代码行数

        程序运行很长时间没有结果:

                jstack进程id,最后的输出,发现死锁

三、本地方法栈(Native Method Stacks)

        不是由java代码编写的方法,native关键字的方法,java间接调用,如hashcode、wait等

四、堆(Heap)

通过new关键字,创建对象都会使用堆内存。

特点:

它是线程共享的,堆中对象都需要考虑线程安全的问题

有垃圾回收机制

堆内存溢出(OutOfMemoryError:Java heap space)

-Xmx 1g

可能运行很长时间才会出现堆内存溢出,可以把内存空间设置小一些,定位排查。

堆内存诊断

1、jps工具

查看当前系统中有哪些java进程

2、jmap工具

查看堆内存占用情况

jmap -heap 进程号

3、jconsole工具

图形界面的,多功能的监测工具,可以连续监测。

案例:垃圾回收后,内存占用依然很高。

jps查看进程id

jmap -heap 进程号

然后执行垃圾回收,内存还是很高

五、方法区(Method Area)

所有java虚拟机线程共享的区,存储类结构相关的信息,是一个运行时常量池,包括成员变量,方法数据,成员方法以及构造器代码,包括特殊方法。

方法区在虚拟机启动的时候被创建。逻辑上是堆的组成部分

方法区内存溢出(OutOfMemoryError)

1.8之前会导致永久代内存溢出

OutOfMemoryError:MetaSpace:PermGen space

1.8之后会导致元空间内存溢出

OutOfMemoryError:MetaSpace

-XX:MaxMetaspaceSize=8m

场景:Spring、mybatis

常量池(二进制字节码)

常量池,就是一张表,虚拟指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息

运行时常量池,常量池是*.class文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值