JVM基础(持续更新)

学习JVM有什么用?

  • 面试

  • 理解底层的实现原理

  • 中高级程序员的必备技能

常见的JVM

image-20220105191454160

学习路线

image-20220105191712863

2、内存结构


2.1 程序计数器

image-20220105191851406

2.1.1 定义

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

2.1.2 作用

作用:记住下一条jvm指令的执行地址

特点:

  • 是线程私有的

  • 不会存在内存溢出

image-20220105192402746

image-20220105192714960

2.2 虚拟机栈

2.2.1 定义

Java Virtual Machine Stacks(Java 虚拟机栈)

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

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

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

image-20220105193030424

演示

package com.caopeng.jvm.t1;

/**

  • @author Crescent_P

  • @date 2022-01-05 19:34

*/

public class Demo1_1 {

public static void main(String[] args) {

method1();

}

private static void method1() {

method2(1,2);

}

private static int method2(int a, int b) {

int c = a + b;

return c;

}

}

image-20220105193925850

问题辨析
  1. 垃圾回收是否涉及栈内存?

答:不涉及,因为栈内存是一次次方法调用产生的栈帧内存、每次方法调用完之后,栈帧会被弹栈,会自动地被回收掉。

  1. 栈内存的分配越大越好吗?

答:不是,因为物理内存是一定的,栈内存越大、线程数会变少。

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

答:判断是否线程安全、就是看多个线程对这个变量是否共享。一个线程对应一个虚拟机栈、一个方法对应一个栈帧,那么方法内的局部变量是对于这个线程来说是私有的。

package com.caopeng.jvm.t1;

/**

  • @author Crescent_P

  • @date 2022-01-05 21:21

  • 局部变量的线程安全问题

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

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

*/

public class Demo1_3 {

public static void main(String[] args) {

StringBuilder sb = new StringBuilder();

sb.append(4);

sb.append(5);

sb.append(6);

// 创建一个新的进程

new Thread(()->{

m2(sb);

}).start();

}

// 不存在线程安全问题

public static void m1(){

// 方法内的局部变量

StringBuilder sb = new StringBuilder();

sb.append(1);

sb.append(2);

sb.append(3);

System.out.println(sb.toString());

}

// 存在线程安全问题

// 作为参数,有可能有其它的线程访问到它

public static void m2(StringBuilder sb){

sb.append(1);

sb.append(2);

sb.append(3);

System.out.println(sb.toString());

}

// 不能

// 会将sb返回,那么其它进程就可能拿到这个sb

public static StringBuilder m3(){

StringBuilder sb = new StringBuilder();

sb.append(1);

sb.append(2);

sb.append(3);

return sb;

}

}

2.2.2 栈内存溢出
栈帧过多导致栈内存溢出

image-20220105212953526

栈帧过大导致栈内存溢出

image-20220105213029073

演示

package com.caopeng.jvm.t1;

/**

  • @author Crescent_P

  • @date 2022-01-05 21:31

  • 显示栈内存溢出

  • -Xss256K

*/

public class Demo1_4 {

private static int count;

public static void main(String[] args) {

try{

method1();

}catch(Throwable e){

e.printStackTrace();

System.out.println("count " + count); // count 34205

}

}

// 没有终止条件,会一直递归调用

private static void method1(){

count++;

method1();

}

}

image-20220105213543006

package com.caopeng.jvm.t1.stack;

import com.fasterxml.jackson.annotation.JsonIgnore;

import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Arrays;

import java.util.List;

/**

  • @author Crescent_P

  • @date 2022-01-05 21:36

  • json 数据转化

*/

public class Demo1_5 {

public static void main(String[] args) throws JsonProcessingException {

Dept d = new Dept();

d.setName(“Market”);

Emp e1 = new Emp();

e1.setName(“zhang”);

e1.setDept(d);

Emp e2 = new Emp();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值