继续上一篇文章讲解,在上一篇中给大家留下了一个小问题,就是在jdk1.6中返回的是两个false,在jdk1.7中返回的是true false,,上一次代码没有贴好,有朋友说运行结果不对。这次把代码贴全 了
首先我们思考我什么两个版本的jdk会不一样,上一篇中我们说到1.7开始去永久代,所有的运行时常量不在装入永生区,在1.6中,intern方法会把首次遇到的字符串实例复制到永生区(真正是复制到常量池,但是常量池在永生代),返回的自然是永生代的实例的引用。一个是永生代的引用,一个是堆中的引用,==比较的是引用,所以肯定false,1.6中的两个false由此可以证实。
而1.7中intern不是复制实例,而是将首次出现的实例引用记录在常量池。所以是true,讲道理,这两个其实都应该是true,前天就有大神朋友提出来了。
昨天我也没思考,其实昨天我把下面的str2写错了,然后直接把1.7的运行结果贴了出来,在此十分抱歉,上图中我把数据换成111最后的结果是true和false,因为第一次将str1写入运行时常量池,然后第二次跟第一次字符串一样,所以返回的是常量池的引用,与堆中不同,所以false。
说完运行池常量,我们来说说大的方向,方法区,方法区存放一些class名,修饰符之类的东西,当然还包括上方的运行池常量。我们要是想造成方法区异常,那么最好的办法就是产生大量的类,(不是产生实例啊,不然方法区没异常,反而堆溢出)。我们不可能去手动写太多的类,只能使用动态生成,当然你也可以复制粘贴许多的jsp,jsp运行时会编译成class,以下代码来自网络
但是最好的办法还是动态生成,了解spring的都知道,spring对类的增强使用的是CGLib,所谓的动态代理,所以今天使用CGLib。
运行结果为OutOfMemoryError:PermGen space,今天方法区溢出也是一种常见的内存溢出异常,