0
点赞
收藏
分享

微信扫一扫

黑马程序员《JVM完整教程》笔记 - p015 - p026

黑马程序员《JVM完整教程》笔记 - p015 - p026


b站链接: 黑马程序员JVM完整教程

本地方法栈

本地方法栈native方法:不是本地创建的方法。
本地方法栈的作用:给本地方法的运行提供一个内存空间。

定义

Heap 堆

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

特点

  • 它是线程共享的,堆中对象都需要考虑线程安全的问题
  • 垃圾回收机制(堆中不再被引用的对象都需要考虑线程安全问题)

堆内存溢出

VM options -Xmx8m 修改堆空间为8M
内存空间调小,较容易暴露出堆内存的问题

堆内存诊断

  1. jps工具
    - 查看当前系统中有哪些java进程
  2. jmap工具
    - 查看某一时刻堆内存占用情况 -heap 进程id
  3. jconsole工具
    - 图形界面的,多功能的监测工具,可以连续监测
public class Demo1_1 {
	public static void main(String[] args) throws InterruptedException {
		System.out.println("1...");
		Thread.sleep(30000);
		byte[] array = new byte[1024 * 1024 * 10]; // 10 Mb
		System.out.println("2...");
		Thread.sleep(30000);
		array = null;
		System.gc();
		System.out.println("3...");
		Thread.sleep(1000000L);
	}
}

在这里插入图片描述
使用jmap监测堆占用情况,在三个时间点抓取内存快照信息
格式:jmap -heap 进程id
jmap
获取到堆的配置信息
堆配置信息
堆内存占用
Eden – 新创建的对象的区域
jconsole

jconsole界面
jconsole具体界面

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

E:\git\jvm\out\production\jvm\cn\itcast\jvm\t1>jps
E:\git\jvm\out\production\jvm\cn\itcast\jvm\t1>jmap -heap 17748 

发现老年代未被回收,使用jvisualvm,监测内存占用,可以执行垃圾回收。

E:\git\jvm\out\production\jvm\cn\itcast\jvm\t1>jvisualvm

jvisualvm
堆 Dump
堆Dump
堆Dump检查
找到问题部分,点开后逐步搜索,找到问题具体位置。

方法区

定义

  • 方法区是所有Java虚拟机线程的一个共享区域,存储了跟类的结构相关的一些信息。主要包括:运行时常量池,方法,构造器,成员方法。
  • 方法区在虚拟机启东时被创建,逻辑上是堆的一个组成部分。具体实现上不同的jvm厂商实现时各不相同,并不强制方法区的位置。
  • 方法区在运行时如果内存不足,也会抛出OutOfMemoryError。
    jvm内存结构
    本地内存:操作系统内存

方法区内存溢出

  • 1.8以前会导致永久代内存溢出
  • 1.8以后会导致元空间内存溢出
/**
 * 演示元空间内存溢出
 * -XX:MaxMetaspaceSize=8m
 */
public class Demo1_2 extends ClassLoader { // 可以用来加载类的二进制字节码
	public static void main(String[] args){
		int j = 0;
		try {
			Demo1_8 test = new Demo1_8();
			for (int i = 0; i < 10000; i++, j++) {
				// ClassWriter 作用是生成类的二进制字节码
				ClassWriter cw = new ClassWriter(0);
				// 版本号,public,类名,包名,父类,接口
				cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);
				// 返回 byte[] 
				byte[] code = cw.toByteArray();
				// 执行了类的加载
				test.defineClass("Class" + i, code, 0, code.length);
			}
		} finally {
			System.ou.println(j);
		}
	}
}

元空间内存溢出:Metaspace
OutOfMemoryError
永久代内存溢出:PermGen space
jvm1.6
场景
- spring
- mybatis

常量池

// 二进制字节码(类基本信息,常量池,类方法定义包含了虚拟机指令)
public class HelloWorld {
	public static void main(String[] args){
		System.out.println("hello world");
	}
}
E:\git\jvm\out\production\cn\itcast\jvm\t5>javap -v HelloWorld.class

-v 操作显示反编译后的详细信息

运行时常量池

  • 常量池,就是一张表,虚拟机指令根据这张表找到要执行的类名,方法名,参数类型,自变量等信息
  • 运行时常量池,常量池是 *.class文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址
    运行时常量池
举报

相关推荐

0 条评论