- 浏览: 341000 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (212)
- spring (21)
- design pattern(java) (12)
- linux-shell (28)
- java-thread (20)
- java-collection (6)
- java-reflect (9)
- mysql (11)
- java-io (7)
- java-util&lang&io (3)
- algorithm (3)
- interview (2)
- tools-eclipse (2)
- tools-maven (1)
- web-script (1)
- java组建 (13)
- 博客收藏 (1)
- 架构设计与实践 (10)
- active-mq (6)
- java-jvm&性能&原理 (27)
- tomcat (2)
- flume (1)
- serialization (2)
- git (1)
- cache&redis (8)
- guava (1)
- zookeeper (3)
- socket&tcp&udp&http (6)
- test (1)
最新评论
-
bbls:
有用有用有用
java-jvm-jstack-(监视器和锁的概念) -
王新春:
小侠有点帅哦 写道此流怎么关闭新春这个实现 可以不关闭的,哈哈 ...
源码剖析之java.io.ByteArrayOutputStream -
小侠有点帅哦:
此流怎么关闭新春
源码剖析之java.io.ByteArrayOutputStream -
cumt168:
写的很好为什么初始化参数,年轻代-Xmn10M def new ...
jvm之内存申请过程分析 -
ronin47:
应该是跟共享域名思路差不多,根据cookie的key作判断
跨域:一种通过服务端解决跨域的实现
----------~开篇分享一句话:【纸上得来终觉浅,绝知此事要躬行】~---------------------------------------
关于String的些许探讨
首先看下面的案例:
------------------------------------------------------------------------------------------------------------------
分析结论:
------------------------------------------------------------------------------------------------------------------
1、String a = "a1"; 变量a对应的字符串a1 分配在了PSPermGen的常量池。
证明思路:
jvm参数配置:-Xmx200M -Xms200M -Xmn100M -XX:SurvivorRatio=8 -XX:+PrintGCDetails -verbose:gc
java代码:
日志:
PSPermGen total 21248K, used 3054K [0x00000000ee600000, 0x00000000efac0000, 0x00000000f3800000)
日志:
PSPermGen total 21248K, used 3057K [0x00000000ee600000, 0x00000000efac0000, 0x00000000f3800000)
证明 PSPermGen区由3054K增长了3K到3057K
2、String a = "ab"; final String bb = "b"; String b = "a" + bb; b同样分配在了常量区
证明思路:
PSPermGen total 21248K, used 3060K [0x00000000ee600000, 0x00000000efac0000, 0x00000000f3800000)
证明:PSPermGen区由3057K->3060K,增长的依旧常量池。
3、String a = "ab"; String bb = "b"; String b = "a" + bb; b分配在了堆区。
证明思路:
方法1、调试 b = "a" + bb; 你会发现代码进入了StringBuilder
方法2如下:
日志:
PSYoungGen total 92160K, used 3276K [0x00000000f9c00000, 0x0000000100000000, 0x0000000100000000)
eden space 81920K, 4% used [0x00000000f9c00000,0x00000000f9f333b0,0x00000000fec00000)
日志:
PSYoungGen total 92160K, used 4916K [0x00000000f9c00000, 0x0000000100000000, 0x0000000100000000)
eden space 81920K, 6% used [0x00000000f9c00000,0x00000000fa0cd160,0x00000000fec00000)
对比说明eden 内存量在减少,说明"a" + bb 在jvm的存在是堆的eden区
关于String的些许探讨
首先看下面的案例:
/** * JVM对于字符串常量的"+"号连接,将程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,拿"a" + 1来说,经编译器优化后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序最终的结果都为true。 */ @Test public void testConstant() { if (true) { String a = "a1"; String b = "a" + 1; System.out.println((a == b)); // result = true } if (true) { String a = "atrue"; String b = "a" + "true"; System.out.println((a == b)); // result = true } if (true) { String a = "a3.4"; String b = "a" + 3.4; System.out.println((a == b)); // result = true } } /** * JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。 */ @Test public void testConstantAB() { String a = "ab"; String bb = "b"; String b = "a" + bb; System.out.println((a == b)); // result = false } /** * 分析:和上面testConstantAB中唯一不同的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。故上面程序的结果为true。 */ @Test public void testConstantFinalAB() { String a = "ab"; final String bb = "b"; String b = "a" + bb; System.out.println((a == b)); // result = true } /** * JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b, * 故上面程序的结果为false。 */ @Test public void testConstantFinalFunctionAB() { String a = "ab"; final String bb = getBB(); String b = "a" + bb; System.out.println((a == b)); // result = false } private static String getBB() { return "b"; }
------------------------------------------------------------------------------------------------------------------
分析结论:
------------------------------------------------------------------------------------------------------------------
1、String a = "a1"; 变量a对应的字符串a1 分配在了PSPermGen的常量池。
证明思路:
jvm参数配置:-Xmx200M -Xms200M -Xmn100M -XX:SurvivorRatio=8 -XX:+PrintGCDetails -verbose:gc
java代码:
public static void main(String[] args) { System.gc(); }
日志:
PSPermGen total 21248K, used 3054K [0x00000000ee600000, 0x00000000efac0000, 0x00000000f3800000)
public static void main(String[] args) { System.gc(); String s1= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; String s4= "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; System.gc();
日志:
PSPermGen total 21248K, used 3057K [0x00000000ee600000, 0x00000000efac0000, 0x00000000f3800000)
证明 PSPermGen区由3054K增长了3K到3057K
2、String a = "ab"; final String bb = "b"; String b = "a" + bb; b同样分配在了常量区
证明思路:
public static void main(String[] args) { System.gc(); final String s1= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; final String s4= "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; String s5 = s1 + s4; System.gc();
PSPermGen total 21248K, used 3060K [0x00000000ee600000, 0x00000000efac0000, 0x00000000f3800000)
证明:PSPermGen区由3057K->3060K,增长的依旧常量池。
3、String a = "ab"; String bb = "b"; String b = "a" + bb; b分配在了堆区。
证明思路:
方法1、调试 b = "a" + bb; 你会发现代码进入了StringBuilder
方法2如下:
public static void main(String[] args) { System.gc(); }
日志:
PSYoungGen total 92160K, used 3276K [0x00000000f9c00000, 0x0000000100000000, 0x0000000100000000)
eden space 81920K, 4% used [0x00000000f9c00000,0x00000000f9f333b0,0x00000000fec00000)
public static void main(String[] args) { String s1= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; String s4= "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; long begin = Runtime.getRuntime().freeMemory(); for(int i=0;i<300;i++){ String temp = s1+"-"+i+"-"+s4; } long end = Runtime.getRuntime().freeMemory(); System.out.println((begin - end)/1024 + "KB"); }
日志:
PSYoungGen total 92160K, used 4916K [0x00000000f9c00000, 0x0000000100000000, 0x0000000100000000)
eden space 81920K, 6% used [0x00000000f9c00000,0x00000000fa0cd160,0x00000000fec00000)
对比说明eden 内存量在减少,说明"a" + bb 在jvm的存在是堆的eden区
发表评论
-
垃圾回收算法详解
2017-05-17 16:42 496可回收对象的判定【收藏,非原创】 讲算法之前,我们先要 ... -
垃圾回收算法&STOP The World
2017-05-15 11:50 658目前所有的新生代gc都是需要STW的: Seria ... -
java-jvm-jhat
2017-05-14 21:04 551功能:可以分析jmap dump下的hprof文件 一般 ... -
java-jvm-jinfo
2017-05-14 20:57 682jinfo: 1、输出 当前java进程启动的相关配置信息 ... -
jvm-gc 日志解读【转载】
2017-05-14 17:34 483转载自:http://ifeve.com/useful-j ... -
大量异常带来性能的影响
2017-05-09 19:08 668感受大量构造异常带来的性能影响: package com; ... -
iotop&iostat (load高 IO高的问题排查)
2017-04-27 20:40 2106目标:使用iotop&top&jstack ... -
java-jvm-jstack-(监视器和锁的概念)
2017-04-06 16:52 6493下面这段jstack的栈信息里,有一个死锁 其中: T ... -
java-jvm-jstack-线程状态
2017-03-31 14:42 2598常见的线程状态: RUNNABLE:正在执行的线程 注 ... -
java-jvm-cpu (cpu)高问题排查
2017-03-28 21:07 33301、通过top命令发现 cpu高的进程 根据top命令, ... -
java-jvm-jstack
2016-08-05 11:07 2193jstack用于打印出给定的java进程ID或core fi ... -
java-jvm好文收集
2016-08-05 10:50 466非常详细GC学习笔记http://blog.csdn.ne ... -
java-jvm-jstat
2016-08-05 10:30 652stat用于监控基于HotSpot ... -
java-jvm-jmap(高内存排查)
2016-07-29 13:51 3806功能:打印出某个java进程(使用pid)内存内的,所有‘对象 ... -
java-jvm-jps
2016-07-29 13:42 468jsp -q 只显示pid,不显示class名称,jar文件 ... -
OutOfMemoryError溢出
2016-03-29 23:29 835Java堆溢出: java.lang.OutOfMemor ... -
垃圾回收器的分类
2016-03-29 22:23 730基础: 串行收集器: DefNew:是使用-XX:+UseSe ... -
ClassLoader-线程上下文类加载器
2015-04-16 10:54 1188线程上下文类加载器 :http://blog.csdn.net ... -
ClassLoader-热替换
2015-04-05 20:27 2744https://www.ibm.com/developer ... -
ClassLoader-学习
2015-04-05 19:03 1068相关文章:https://www.ib ...
相关推荐
JVM 内存分配与垃圾回收是 JVM 中两个非常重要的概念,本文将对 JVM 内存分配与垃圾回收进行详细的解释。 JVM 运行时数据区域 JVM 内存分配主要涉及到五个运行时数据区域:程序计数器、Java 虚拟机栈、本地方法栈...
本文将详细讲解如何查看JVM中的线程活动情况,并提供相关示例代码。 首先,Java提供了`java.lang.management.ThreadMXBean`接口,它是管理JVM线程的管理接口。通过这个接口,我们可以获取线程的各种信息,包括线程...
- **JVM参数**:可以配置JVM启动时的参数,用于优化内存分配、垃圾回收等方面。 - **类文件解析**:JVM将类文件中的字节码转换成计算机能够理解的指令执行。 #### 10. 常用工具 - **VisualVM**:是一个可以监控运行...
例如ldc命令将int, float或String型常量值从常量池中推送至栈顶,ldc_w命令将int, float或String型常量值从常量池中推送至栈顶(宽索引),ldc2_w命令将long或double型常量值从常量池中推送至栈顶(宽索引)。...
在Java虚拟机(JVM)中,`String.intern()` 是一个非常特殊且重要的方法,它与字符串常量池紧密相关。字符串常量池是一种内存优化机制,存储了程序中所有的字符串字面值和通过 `intern()` 方法添加的字符串。这个池...
`main()`函数通常包含初始化参数`String[] args`,这部分的局部变量会在栈帧中分配空间。 ##### Min()函数的调用 当从`main()`函数中调用`Min()`函数时,JVM会创建一个新的栈帧来保存局部变量和参数,并跳转到相应...
Java中的动态内存分配主要在堆上进行,垃圾收集器也会对堆进行管理,进行垃圾回收。 2. 方法区:存储类信息、常量、静态变量等,也被称为非堆或永久代。在较新的JVM版本中,这部分已经被元空间(Metaspace)所替代...
**ClassLoader** 负责加载ClassFile到JVM中,它遵循双亲委派模型。常见的ClassLoader包括Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader。 #### 四、内存模型、锁与同步 **Java内存模型** 主要...
在Java编程中,String类是使用最频繁的类之一,它涉及到许多底层机制,特别是与JVM(Java虚拟机)的交互。本文将探讨String类的一些关键特性,包括字面量与运行时常量池、String的intern()方法以及它们如何影响内存...
`String` 对象的创建涉及复杂的内存分配机制,特别是在Java虚拟机 (JVM) 的环境中。本文将详细介绍创建 `String` 对象过程中涉及的不同内存区域,以及不同创建方式下内存分配的过程。 #### 二、内存分配概述 在Java...
在某些JVM实现中,它与Java虚拟机栈合并在一起。 ##### 4.5 方法区(Method Area) 方法区存储了每个类的信息(包括类的方法和字段)、常量池、静态变量等。它是共享的内存区域,用于存放所有类的信息。 #### 五、...
例如,Java的`int`在JNI中是`jint`,`String`是`jstring`。对于复杂类型,如数组或对象,需要使用特定的JNI函数进行处理。 在提供的资源"使用C++创建java虚拟机JVM,使用JNI调用java函数"中,可能详细介绍了以上...
在Java开发中,JVM(Java Virtual Machine)是至关重要的组成部分,它负责运行所有的Java应用程序。JVM性能优化是一项细致而关键的任务,能够显著提升程序的运行效率,减少资源消耗,提高系统稳定性。本PPT详细探讨...
Java程序的运行依赖于类加载器将`.class`文件加载到JVM中,并对其进行验证、准备和解析等步骤,最终使类能够在JVM中执行。 #### 三、Class文件的加载过程 Java类的加载过程主要可以分为以下几个阶段: 1. **加载...
新生代收集担保是确保在Minor GC期间,如果新生代的对象无法全部转移到Survivor区,JVM有足够的空间在老年代进行分配。关闭此功能可能导致在某些情况下更频繁的Full GC,但可以减少内存浪费和潜在的性能提升。 在...
常量池是JVM中一个重要的概念,用于存储编译期间生成的字面量和符号引用。常量池有两种形式:静态常量池和运行时常量池。 静态常量池是class文件中的常量池,包含字符串(数字)字面量、类、方法的信息,占用class...
- 特殊情况下直接在 Old 区分配,如大对象或长时间存活的对象。 - TLAB (Thread Local Allocation Buffer) 是一种优化技术,允许每个线程拥有自己的缓冲区,从而加快分配速度。 2. **栈上分配**: - 适用于原子...
如果`value`中有空格,则需要用双引号将该值括起来,如`-Dname="space string"`。这个参数常用于设置系统级全局变量值,例如配置文件路径。 - **示例**:`-Dconfig.file=C:\conf\application.properties`。 #####...
原始类型在内存中直接存储值,而引用类型存储的是对象的引用地址。 3. 类文件格式: Java源代码编译后生成.class文件,其内部结构遵循特定的格式。主要包括魔数、版本号、常量池、访问标志、类索引、父类索引、...