下面是一个例子
import java.nio.charset.StandardCharsets; public class test2 { public static void main(String[] args) { String str = "北京时间8月6日,东京奥运会进入尾声阶段,摔跤赛事也进入了到了白热化阶段。在今日傍晚进行的女子自由式摔跤50公斤级决赛中, 孙亚楠面对日本选手须崎优衣,在经过一番激烈角逐后,孙亚楠在决赛被对手利用滚桥战术连得比分,最终0:10不敌须崎优衣,获得一枚银牌。规则:摔跤比赛分为自由式摔跤与古典式摔跤,自由式摔跤可以用腿等腰下部位攻击对手。一共分为两回合,也称上下半场,最后按照双方得分判定胜利归属。此外,如果出现长时间压制无法起身的情况,被压制一方直接判负。孙亚楠是中国摔跤队核心运动员之一,暨2013世锦赛冠军得主、2016年里约奥运会女子自由式48公斤级铜牌获得者。东京奥运会周期,孙亚楠进行了小幅增重。1/8决赛,孙雅楠面对古巴选手洛佩斯,8: 2晋级;1/4决赛,孙亚楠面对乌克兰选手,7:3晋级。半决赛,孙亚楠则是在0:7落后的情况下,10:7惊天逆转晋级。女子自由式摔跤50公斤级决赛 孙亚楠VS须崎优衣(日本)第一回合,孙亚楠与须崎优衣都比较谨慎,双方前15秒都在互相试探和把位,感受对方的节奏和力量,并没有进行有效进攻,从体型上来看,可以看到双方都是敏捷型的选手,速度很快。比赛进行到20秒左右,须崎优衣尝试一个抱摔,但没有能够得手。前1分钟双方都未能得分,须崎优衣的攻势十分猛烈,拿到了一个优势身位,随后拿到2个技术分。孙亚楠陷入被动,被对手利用滚桥战术连拿8分,陷入了0:10的落后,按照摔跤比赛的规则,孙亚楠0:10是要直接判负的。如此,比赛还未进行到2分钟,孙亚楠也是只能遗憾落败,最终拿到一枚银牌。"; System.out.println(subStr(str, 6)); } private static String subStr(String origin, int length){ if (origin == null || origin.length() == 0 || length <= 0){ return origin; } try { int originLength = origin.getBytes(StandardCharsets.UTF_8).length; if (originLength > length){ origin = origin.substring(0, origin.length() - 1); origin = subStr(origin, length); } }catch (Exception e){ e.printStackTrace(); } return origin; } }
用到递归,传入的originc长度比较大,length太小的时候,递归太深,效率低,耗内存,可能栈溢出。
下面是设置jvm栈内存参数 -Xss128k时候,抛出的异常
"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" -Xss128k "-javaagent:D:\IntelliJ IDEA 2021.1.2\lib\idea_rt.jar=54870:D:\IntelliJ IDEA 2021.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_201\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\rt.jar;F:\person_code\jvm_deep_base\module04\target\classes" test2 Exception in thread "main" java.lang.StackOverflowError at sun.nio.cs.UTF_8$Encoder.isLegalReplacement(UTF_8.java:566) at java.nio.charset.CharsetEncoder.replaceWith(CharsetEncoder.java:299) at java.nio.charset.CharsetEncoder.<init>(CharsetEncoder.java:207) at java.nio.charset.CharsetEncoder.<init>(CharsetEncoder.java:233) at sun.nio.cs.UTF_8$Encoder.<init>(UTF_8.java:558) at sun.nio.cs.UTF_8$Encoder.<init>(UTF_8.java:554) at sun.nio.cs.UTF_8.newEncoder(UTF_8.java:72) at java.lang.StringCoding.encode(StringCoding.java:348) at java.lang.String.getBytes(String.java:941) at test2.subStr(test2.java:15) at test2.subStr(test2.java:18)
修改方案,去掉递归