1、运行命令,输入密码 即可弹出
sudo java -cp $JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.HSDB
2、创建测试类,以便查看具体的对象状态,代码如下
/**
* @author
* JVM参数
* -Xms30m -Xmx30m -XX:MaxMetaspaceSize=30m -XX:+UseConcMarkSweepGC -XX:-UseCompressedOops
*
*
*/
public class JVMObject {
public final static String MAN_TYPE = "man"; // 常量
public static String WOMAN_TYPE = "woman"; // 静态变量
public static void main(String[] args)throws Exception {
Teacher T1 = new Teacher();
T1.setName("李四");
T1.setSexType(MAN_TYPE);
T1.setAge(36);
for(int i =0 ;i<15 ;i++){
System.gc();//主动触发GC 垃圾回收 15次--- T1存活
}
Teacher T2 = new Teacher();
T2.setName("张三");
T2.setSexType(MAN_TYPE);
T2.setAge(18);
Thread.sleep(Integer.MAX_VALUE);//线程休眠
}
}
class Teacher{
String name;
String sexType;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSexType() {
return sexType;
}
public void setSexType(String sexType) {
this.sexType = sexType;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
运行代码,运行之前请先设置虚拟机参数(垃圾回收器CMS)
-Xms30m -Xmx30m -XX:MaxMetaspaceSize=30m -XX:+UseConcMarkSweepGC -XX:-UseCompressedOops
3、在命令行上 jps 命令查看该类的进程ID
上图中可以看到实际 JVM 启动过程中堆中参数的对照,可以看到,在不启动内存压缩的情况下。堆空间里面的分代划分都是连续的,而且其中分为新生代(PSYoungGen)【eden、from、to】和老年代(PSOldGen)
选择 OBject Histogram 查看运行代码中Teacher 对象在内存中的位置,双击进入
从上图中可以验证栈内存,同时也可以验证到虚拟机栈和本地方法栈在 Hotspot 中是合二为一的实现了。
总结
当我们通过 Java 运行以上代码时,JVM 的整个处理过程如下:
- JVM 向操作系统申请内存,JVM 第一步就是通过配置参数或者默认配置参数向操作系统申请内存空间。
- JVM 获得内存空间后,会根据配置参数分配堆、栈以及方法区的内存大小。
- 完成上一个步骤后, JVM 首先会执行构造器,编译器会在.java 文件被编译成.class 文件时,收集所有类的初始化代码,包括静态变量赋值语句、
静态代码块、静态方法,静态变量和常量放入方法区
- 执行方法。启动 main 线程,执行 main 方法,开始执行第一行代码。此时堆内存中会创建一个 Teacher 对象,对象引用 student 就存放在栈中。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。