JVM三大性能调优参数-Xms -Xmx -Xss的含义
1.-Xss:规定了每个线程虚拟机栈(堆栈)的大小。
256k足够,此配置将会影响此进程中并发线程数的大小
2.-Xms:初始的java堆大小
即,该进程刚创建出来的时候,它的专属java堆的大小。一旦对象容量超过java堆的初始容量,java堆将会自动扩容,最大扩容大小的-Xmx
3.-Xmx:java堆能扩展到的最大值
一般情况下,将Xms和Xmx设成一样,因为当heap不够用,发生扩容时,会发生内存抖动,影响程序运行时的稳定性。
JAVA内存模型中堆和栈的区别?
-内存分配策略
程序运行时,有三种内存分配策略:静态的、栈式的、堆式的。
静态存储:编译时确定每个数据目标在运行时的存储空间需求。因而在程序编译时就可以给它们分配固定的内存空间。这种分配策略要求程序代码中不允许有可变数据结构的存在,也不允许有嵌套或者递归的结构出现。
栈式存储:数据区需求在编译时未知,运行时模块入口前确定。动态的存储分配,由一个堆栈的运行栈实现的。规定在进入一个程序模块的时候,必须知道这个程序模块所需要的内存大小。按照先进后出的原则进行分配。
堆式存储:编译时或运行时模块入口都无法确定,动态分配。堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放。
堆和栈的联系:
堆内存创建出对象实例,将其首地址赋值给p,并保存在当前内存的虚拟机栈内存中,这样通过访问地址P,就可以轻松调用存在堆内存中的对象实例。
堆和栈的区别:
1.管理方式:栈自动释放,堆需要GC。JVM可以针对内存栈进行管理操作,
而且该内存的释放是编译器就可以操作的内容。
2.空间大小:栈比堆小。
3.碎片相关:栈产生的碎片远小于堆。对于堆空间而言,即使垃圾回收器可以进行自动堆内存回收,但是堆空间的活动量相对于栈空间而言比较大,很有可能存在长时间的堆空间分配和释放操作。而且垃圾回收器不是实时的,它有可能使得堆空间的内存碎片,逐渐累积起来。
4.分配方式:栈支持静态和动态分配,而堆仅支持动态分配。
5.效率:栈的效率比堆高。
元空间、堆、线程独占部分间的联系?
-内存角度
元空间保存的是加载进来的类。
Java堆保存的对象实例。
当程序执行的时候,分配对应的虚拟机栈,本地栈和程序计数器。虚拟机栈保存本地变量test的地址引用和对象hw的地址引用,局部变量a=1,LineNo是行号。
不同JDK版本之间的intern()方法的区别-JDK6 VS JDK6+
例子:
JDK 1.6下
每次创建inter方法,就往字符串常量池中添加字符串对象。
将永久代的容量调下一点
运行程序报错,字符串对象将常量池挤爆了。Jdk6前,永久代存在,并且永久代里面有字符串常量池。
JDK7下
程序正确的执行。将字符串常量池从永久代移动到了堆内存之后PermGen space异常得到了解决。
比较inter的不同
Jdk6+:
Jdk6:
New是在java heap区域创建,s2=”a”是放在字符串常量池中。
JDK6:
s创建的时候,首先在常量池中创建“a”,然后在heap中创建了string对象。当使用intern时,企图将string对象放到常量池中,但是常量池已经有a了,所以放置失败。定义s2时,直接使用了常量池中的a,所以两个地址不一样。
创建s3时,在heap中创建string对象,使用intern函数,将对象的副本放置到常量池中,s4引用常量池中的aa,但是由于是string对象的副本,所以两个的地址不同
s创建的时候,首先在常量池中创建“a”,然后在heap中创建了string对象。当使用intern时,企图将string对象放到常量池中,但是常量池已经有a了,所以放置失败。定义s2时,直接使用了常量池中的a,所以两个地址不一样。
创建s3时,在heap中创建string对象,使用intern函数,将对象的引用放置到常量池中,s4引用常量池中的aa,由于是string对象的引用,所以两个的地址相同。