首页 > 试题广场 >

以上述代码为基础,在发生过一次FullGC后,上述代码在He

[单选题]
static String str0="0123456789";
static String str1="0123456789";
String str2=str1.substring(5);
String str3=new String(str2);
String str4=new String(str3.toCharArray());
str0=null;
假定str0,...,str4后序代码都是只读引用。
Java 7中,以上述代码为基础,在发生过一次FullGC后,上述代码在Heap空间(不包括PermGen)保留的字符数为()
  • 5
  • 10
  • 15
  • 20
推荐
应该是C
substring实际是new,5字符
str3和4也都是new,每个5字符
分别都会创建新的对象
常量池是PermGen的
因此应该是一共15字符
编辑于 2015-06-17 21:15:35 回复(31)

解析:这是一个关于java的垃圾回收机制的题目。垃圾回收主要针对的是堆区的回收,因为栈区的内存是随着线程而释放的。堆区分为三个区:年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,也就是方法区)。

 年轻代:对象被创建时(new)的对象通常被放在Young(除了一些占据内存比较大的对象),经过一定的Minor GC(针对年轻代的内存回收)还活着的对象会被移动到年老代(一些具体的移动细节省略)。

年老代:就是上述年轻代移动过来的和一些比较大的对象。Minor GC(FullGC)是针对年老代的回收

永久代:存储的是final常量,static变量,常量池。

str3,str4都是直接new的对象,而substring的源代码其实也是new一个string对象返回,如下图:


经过fullgc之后,年老区的内存回收,则年轻区的占了15个,不算PermGen。所以答案选C
发表于 2015-10-05 20:53:53 回复(47)
不懂呀
发表于 2015-04-23 09:54:43 回复(0)
????不明白
发表于 2015-03-16 00:10:13 回复(0)
选C 方法区:主要存储结构信息的地方,比如方法体,同时也是存储静态变量,以及静态代码块的区域,构造函数,常量池,接口初始化等等 方法区物理上还是在堆中,是在堆的持久代里面。堆有年轻代 (由一个Eden区和俩个survivor区组成),老年代,持久代。新创建的对象都在年轻代的Eden区,经过一次JC收集后,存活下来的会被复制到survivor区(一个满了,就全部移动到另外一个大的中,但要保证其中一个survivor为空),经过多次JC后,还存活的对象就被移到老年代了。 持久代就是经常说的方法区里面存放类信息,常量池,方法等 static String str0="0123456789"; static String str1="0123456789";是放在方法区里。也就是持久代,题目中已经说了,不包含持久代,所以剩余空间为5+5+5=15.
发表于 2015-08-13 17:14:30 回复(10)
发表于 2016-08-30 22:28:18 回复(19)
看不懂
发表于 2015-03-16 09:49:10 回复(0)
heap中还有15个字符。

发表于 2018-07-21 19:07:04 回复(3)
   D 20个
    static String str0="0123456789";
    static String str1="0123456789";//java1.7 常量池从方法区转到了堆 +10
    
    public static void main(String[] args) {
        String str2=str1.substring(5);//jdk1.7会重新复制一个char[]数组,+5
        String str3=new String(str2);//引用原来的str2 的字符堆里面没有增加字符数
        String str4=new String(str3.toCharArray());//str3.toCharArray 复制了一个新的char数组 在堆了新增加了5个字符
        str0=null;
    }
编辑于 2015-08-14 09:32:21 回复(13)
应该选C
java中内存区域分为4类:
栈内存空间,存放引用的堆内存空间的地址
堆内存空间,存放new出来的对象
全局数据区,保存static类型属性和全局变量
全局代码区,保存所有方法的定义
所有str0和str1不会在堆区,str2和str3和str4分别在堆内存开辟空间,所以是15

发表于 2015-09-09 15:27:50 回复(1)
其他变量都来自常量池,不看,new出来的对象存在于堆中,就是str3和str4,str2的substring实际上也在堆中创建了一个新的对象,他们的值都是5个,所以是15
发表于 2015-06-18 11:37:18 回复(1)
首先,选B。
JDK 7 的字符常量池搬家到了Heap。
str0 ,str 1 不会被GC,这两个引用都指向常量池的同一个 字符串对象。但是不在heap中。
str2 是新的存储地址,heap +5
str3内部的存储引用和str2是同一个内存区域。+0
str4又是新的+5
具体可以参考JDK7的 源码。
编辑于 2016-09-14 10:01:11 回复(8)
举例说明 字面量创建形式 String str1="droid"; JVM检测这个字面量,这里我们认为没有内容为droid的对象存在。JVM通过字符串常量池查找不到内容为droid的字符串对象存在,那么会创建这个字符串对象,然后将刚创建的对象的引用放入到字符串常量池中,并且将引用返回给变量str1。 如果接下来有这样一段代码: String str2="droid"; 同样JVM还是要检测这个字面量,JVM通过查找字符串常量池,发现内容为”droid”字符串对象存在,于是将已经存在的字符串对象的引用返回给变量str2。注意这里不会重新创建新的字符串对象。 验证是否为str1和str2是否指向同一对象,我们可以通过这段代码 System.out.println(str1==str2); 输出:True. 使用new创建 String str3=new String("droid"); 当我们使用了new来构造字符串对象的时候,不管字符串常量池中有没有相同内容的对象的引用,新的字符串对象都会创建。因此我们使用下面代码测试一下, System.out.println(str1==str3); 结果返回:False 表明这两个变量指向的为不同的对象。 这里有一点要注意,对于通过new方式创建的String对象,每次都会在Heap上创建一个新的实例,但是对于字符串字面量的形式,只有当字符串常量池中不存在相同对象时才会创建。
发表于 2017-04-09 00:41:19 回复(0)

这是一个关于java的垃圾回收机制的题目。垃圾回收主要针对的是堆区的回收,因为栈区的内存是随着线程而释放的。堆区分为三个区:年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,也就是方法区)。

 年轻代:对象被创建时(new)的对象通常被放在Young(除了一些占据内存比较大的对象),经过一定的Minor GC(针对年轻代的内存回收)还活着的对象会被移动到年老代(一些具体的移动细节省略)。

年老代:就是上述年轻代移动过来的和一些比较大的对象。Minor GC(FullGC)是针对年老代的回收

永久代:存储的是final常量,static变量,常量池。

str3,str4都是直接new的对象,而substring的源代码其实也是new一个string对象返回,如下图:


经过fullgc之后,年老区的内存回收,则年轻区的占了15个,不算PermGen。所以答案选C
发表于 2016-01-08 11:21:57 回复(0)

Java 6及以前,字符串常量池存放在永久代(Permanent Generation),Java 7及以上版本,将字符串常量池的位置调整到Java堆中。substring()的源代码其实也是new一个string对象返回。所以,str2变量所指向的对象,保存在堆中,其保存的内容是"56789"。str3和str4变量所指向的对象,虽然也是存放在堆中,但其保存的应该是str2变量所指向对象的内存地址,而不是字符。这里要注意一点,str2、str3和str4变量所指向的对象不是同一个对象。

str1变量本身是保存在永久代,但"0123456789"这个字符串是保留在常量池中的。因此,保留的字符数是"0123456789"和"56789"这15个字符。

发表于 2022-08-09 09:36:08 回复(0)
个人理解,个人观点

本题一共就创建了两个字符串常量 “0123456789” 和“56789”
而且又是JDk 7 ,字符串常量池在方法区中,而且方法区又是永久代实现,在堆中
最后我们发生FullGC回收,不包括 permGC(永久代回收),所以我们的字符串一个都没有回收,所以,FullGC后还有10+5 = 15个字符

发表于 2022-03-19 17:06:33 回复(0)
staticString str0="0123456789";
// str0 变量存储在栈中,常量字符串存储在方法区中
staticString str1="0123456789";
String str2=str1.substring(5);
// 调用substring方法实际上是创建了一个String对象,创建的对象是放在新生代中,所以一个有3个对象在新生代
// str0 = null并不影响存储在新的中的String对象,在一次GC后,任然在新生代中(JVM默认新生代中经历16次GC任然存活的对象才放到老年代),所以是3的倍数,选C
String str3=newString(str2);
String str4=newString(str3.toCharArray());
str0=null;
发表于 2019-09-12 23:25:56 回复(0)

substring() 方法返回字符串的子字符串。

语法

public String substring(int beginIndex)  public String substring(int beginIndex, int endIndex)

参数

  • beginIndex -- 起始索引(包括), 索引从 0 开始。

  • endIndex -- 结束索引(不包括)。

发表于 2022-05-03 17:07:33 回复(0)
查了一下jdk7的方法区常量池在堆中,以这个为前提。 (1)str0和str1都指向一个常量池中的同一个空间,该字符串长度为10。 (2)str234在堆中都创建了value属性指向堆中的常量池,而str2和str3的两个对象的value都指向常量池的同一个空间(即从第五位往后开始的字符串常量,长度为5)。对于str4,其传入的是char数组,在string构造器初始化时应该会调用方法将其转为字符串,所以传入的其实就是str3,只是系统帮重复转换,同样的,str4也会在堆中创建一个value,其指向常量池,常量池中str3的字符串常量已经存在,故不会开辟新空间。所以其实堆中的字符就是常量区中的字符,从头到尾只有两个(“0123456789”,“56789”)所以其字符数是15个。 这是我粗略见解,请各位大神指正。
发表于 2022-04-22 19:31:09 回复(1)
Full GC :是清理整个堆空间—包括年轻代和老年代
然后堆中只剩下上边创建的三个对象。一共15个字符。

发表于 2022-01-29 14:54:24 回复(0)

这是一个关于java的垃圾回收机制的题目。垃圾回收主要针对的是堆区的回收,因为栈区的内存是随着线程而释放的。堆区分为三个区:年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,使用永久代来实现方法区)jdk1.7及以后,常量池逐步从永久代中移出,在堆内另外开辟了一块空间。

 年轻代:对象被创建时(new)的对象通常被放在Young(除了一些占据内存比较大的对象),经过一定的Minor GC(针对年轻代的内存回收)还活着的对象会被移动到年老代(一些具体的移动细节省略)。

年老代:就是上述年轻代移动过来的和一些比较大的对象。Minor GC(FullGC)是针对年老代的回收

永久代:存储的是final常量,static变量,常量池。

str3,str4都是直接new的对象,而substring的源代码其实也是new一个string对象返回,如下图:


经过fullgc之后,年老区的内存回收,则年轻区的占了15个,不算PermGen。所以答案选C

常量池是介于栈和堆外的另一种独立的内存管理空间,相同内容常量池中永远只有一份,基本数据类型、对象的引用都存在栈中,执行速度快,包装类型,对象存储,new出来的对象都是存储在堆中,Byte,Short,Integer,Long,Character这5种整型的包装类只是在对应值小于等于127时才可使用对象池。超过了就会堆内创建新对象,所有才会出现上述情况,而String是个较为特殊的包装类型,直接用=“”创建的数据是存放在常量池,且无论数据大小都不会申请空间创建,除非使用new关键字。
发表于 2019-11-02 10:12:52 回复(0)