标签:
本节小汪重点介绍下java内存,首先提问:
1.jvm内存如何分配
2.为什么要划分新生代和老年代,实践中究竟哪些属于新哪些属于旧
3.简要介绍一下jstat -gc 如何
内存分为堆栈两部分
栈:线程私有
堆:线程共享
栈:
程序计数器:当前线程所执行的字节码行号指示器 控制代码字节的执行
java虚拟机栈:描述的是java方法执行的内存模型,方法从调用到完成就对应一个栈帧在虚拟机栈中入栈到出栈的过程。
栈帧:一种数据结构 用于存储局部变量、操作数栈、动态链接、方法出口
本地方法栈:为虚拟机栈的Native方法服务
堆:
Java堆:存java对象实例
方法区(Non-Heap,永久代):常量、静态变量、类信息
运行时常量池:方法区的一部分,编译期的字面量和符号引用
public class MyThreadPrinter2 implements Runnable {
private String name;
private Object prev;
private Object self;
private static int num = 12;
private MyThreadPrinter2(String name, Object prev, Object self) {
this.name = name;
this.prev = prev;
this.self = self;
}
@Override
public void run() {
int count = 10;
System.out.println(count);
}
public static void main(String[] args) throws Exception {
Object a = new Object();
Object c = new Object();
MyThreadPrinter2 pa = new MyThreadPrinter2("A", c, a);
new Thread(pc).start();
}
}
该代码产生了对象和线程,并执行该线程,下面分析一下当main方法执行时jvm内存情况
1.
Object a = new Object();
Object c = new Object();
Java堆里会产生两个Object对象
栈里本地变量表产生两个reference类型 a和c 分别引用了堆中的两个对象实例
2.
MyThreadPrinter2 pa = new MyThreadPrinter2("A", c, a);
Java堆中产生一个MyThreadPrinter2对象 对象中包含了name prev self这几个变量
同时静态num被保存到了方法区中
栈里本地变量表产生pa并指向MyThreadPrinter2对象
run方法信息有关的字面量会保存在方法区中
3.
new Thread(pc).start();
产生一个线程对象 并调用run方法
在栈中会针对该线程对象产生相应栈帧
4.
public void run() {
int count = 10;
System.out.println(count);
}
run方法中的本地变量表会生成一个count并赋值为10
最终该方法的运行会通过指令集对栈帧进行出栈操作并计算来完成。
从内存回收的角度 java堆分为新生代、老年代、永久代
永久代:方法区的内容放在这里
新生代:首次生成的对象或数组
老年代:首次生成的大对象或经过N次垃圾回收后仍存活的对象
每次回收老年代也会回收永久代
标签:
原文地址:http://blog.csdn.net/tracymm19891990/article/details/42360737