虚拟机分为:系统虚拟机(比如VMware)、程序虚拟机(比如Java虚拟机)
1、堆、栈、方法区
图中创建user对象,就是根据方法区中的User类信息来创建的。
1)当user是成员字段。那么每一个线程进来时,都会操作同一个堆中的实例,所以成员字段对应的实例是线程共享的。(操作的是同一个变量引用,引用指向的实例也是同一个)
2)当user是局部变量。那么每一个线程进来时,都会各自在堆中创建一个实例,该实例由该线程私有,所以局部变量对应的堆中实例是线程私有的。(操作的是各自的引用,引用指向的也是各自的实例)
问题:如果一个成员字段,在方法中使用时,重新赋值了,而不是直接使用。那么该引用或引用指向的堆中实例是线程安全的吗?不是。
总结:
多线程环境下,成员字段的引用只有一个,指向的堆中实例也只有一个(不管方法中是否重新赋值)。(所以成员字段线程共享)
局部变量,每个线程都有自己的引用,指向堆中各自的实例。(所以局部变量线程安全)
二、辨清java堆
三、Java栈
四、Java方法区
五、虚拟机参数
jvm参数配置:
(1)-XX 对于系统级别的配置(jvm),如配置日志信息,或者配置使用哪种垃圾回收器
(2)非-XX 基本上都是应用层面上的配置。如配置堆、栈、方法区的内存大小(每一个Java程序都可以分别配置自己要使用的堆栈方法区的大小)(每一个jvm上可以运行多个Java程序)
+ 启用
- 禁用
main方法运行时,run configuration, 添加jvm参数: 设置当前程序的堆内存大小,和打印jvm信息
-Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
更细粒度的堆内存设置
堆溢出时,导出整个堆的信息
测试打印堆溢出信息,jvm参数:
-Xms2m -Xmx2m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump
java栈配置
可以在try catch捕获异常时,打印调用次数。catch(throwable t)Exception的父类方法区配置(以前以为方法区属于堆的一部分,这么看不是)
直接内存配置
oom内存溢出(如果自己写原生的NIO程序时,可以试试配置,netty框架不用)jvm不错的博客:
http:www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html
网友评论