1. 多线程并发访问一个静态方法(static method)会不会有什么性能影响?
思考:不会,原因是static method编译后及时一串指令(jvm中的静态方法区,也叫non-heap(包含了Perm Gen),jvm规范对该区没有GC 要求);
如果没有数据竞争,就不会有并发不安全的问题。
那个数据调用了改方法,则对改数据做一系列的指令。
2.所谓的minor GC ,full GC 和常见的内存溢出,你的理解是什么?
思考:jvm 内存模型分几大区域:栈(线程)、堆(实例)、静态方法区(class,method等),
GC 都是发生在堆内存(heap),堆中分为一个Eden、两个survivor、一个Tunured;清空Eden叫minor GC,清空Tenured叫full GC ,suvivor完成数据的交换。
内存溢出在可以发生在任何区域
栈帧溢出:StackOverflowError:Thrown when a stack overflow occurs because an application recurses too deeply.(-Xss 2048K 可以调整每个线程的栈内存容量)
堆溢出:OutOfMemoryError:Java heap space (调整参数为-Xms128m -Xmx521m)
静态方法栈溢出:OutOfMemoryError:PermGen space (调整参数为: -XX:PermSize=256m -XX:MaxPermSize=512m)
3.关于static、final、static final修饰的变量 你有什么理解?
static 和 final 修饰的变量:在 Perm Gen(方法区)中。
而static final两个修饰符同时修饰的变量 并不在此区域中。
验证代码和现象如下:
package demo;public class Test { public static void main(String[] args) { try { Thread.sleep(10*1000); System.out.println(ConstA.str10000);// Perm Gen 内存明显增长 Thread.sleep(10*1000); System.out.println(new ConstB().str10001);// Perm Gen 内存明显增长 Thread.sleep(10*1000); System.out.println(new ConstB().str10002);// 无明显变化 Thread.sleep(10*1000); System.out.println(ConstC.str10000);//无明显变化 Thread.sleep(10*1000); } catch (Exception e) { e.printStackTrace(); } }}
这个例子有些值得思考的地方:比如static final为何没有出现在PermGen中,我去查阅了有关资料,说static final是编译期常量,不会引发类的初始化。(http://www.cnblogs.com/jxzheng/p/5191037.html)
于是,我在test中加了一行代码:Class.forName()
package demo;public class Test { public static void main(String[] args) { try { Thread.sleep(10*1000); System.out.println(ConstA.str10000);// Perm Gen 内存明显增长 Thread.sleep(10*1000); System.out.println(new ConstB().str10001);// Perm Gen 内存明显增长 Thread.sleep(10*1000); System.out.println(new ConstB().str10002);// 无明显变化 Thread.sleep(10*1000); Class.forName("demo.ConstC"); System.out.println(ConstC.str10000);//20秒后,内存开始变化 Thread.sleep(10*1000); } catch (Exception e) { e.printStackTrace(); } }}