java怎么增加堆栈_如何增加Java堆栈大小?「建议收藏」

java怎么增加堆栈_如何增加Java堆栈大小?「建议收藏」如何增加Java堆栈大小?我问了这个问题,以了解如何增加JVM中的运行时调用堆栈大小。我已经得到了一个答案,而且我也得到了很多有用的答案和评论,这些答案和评论与Java如何处理需要大型运行时堆栈的情况相关。我已经回答了问题的总结。最初我想增加JVM堆栈的大小,所以像没有StackOverflowError运行的程序。publicclassTT{publicstaticlongfa…

大家好,又见面了,我是你们的朋友全栈君。

如何增加Java堆栈大小?

我问了这个问题,以了解如何增加JVM中的运行时调用堆栈大小。 我已经得到了一个答案,而且我也得到了很多有用的答案和评论,这些答案和评论与Java如何处理需要大型运行时堆栈的情况相关。 我已经回答了问题的总结。

最初我想增加JVM堆栈的大小,所以像没有StackOverflowError运行的程序。

public class TT { public static long fact(int n) { return n < 2 ? 1 : n * fact(n – 1); } public static void main(String[] args) { System.out.println(fact(1 << 15)); } }

相应的configuration设置是具有足够大的值的java -Xss…命令行标志。 对于上面的程序TT ,它可以像OpenJDK的JVM一样工作:

$ javac TT.java $ java -Xss4m TT

其中一个答案也指出-X…标志是依赖于实现的。 我正在使用

java version “1.6.0_18” OpenJDK Runtime Environment (IcedTea6 1.8.1) (6b18-1.8.1-0ubuntu1~8.04.3) OpenJDK 64-Bit Server VM (build 16.0-b13, mixed mode)

也可以为一个线程指定一个大堆栈(请参阅其中一个答案)。 这是比java -Xss…推荐,以避免浪费内存的线程不需要它。

我很好奇上面的程序需要多大的堆栈,所以我运行它增加了:

-Xss4m可以满足fact(1 << 15)

-Xss5m可以满足fact(1 << 17)

-Xss7m可以满足fact(1 << 18)

-Xss9m可以满足fact(1 << 19)

-Xss18m可以满足fact(1 << 20)

-Xss35m可以满足fact(1 << 21)

-Xss68m可以满足fact(1 << 22)

-Xss129m可以满足fact(1 << 23)

-Xss258m可以满足fact(1 << 24)

-Xss515m可以满足fact(1 << 25)

从上面的数字看来,Java对于上面的函数使用每个栈帧大约16个字节,这是合理的。

上面的枚举包含的可以 是足够的 ,因为堆栈需求是不确定的:使用相同的源文件多次运行它,相同的-Xss…有时成功,有时会产生StackOverflowError 。 例如,对于1 20, -Xss18m已经足够用于10次中的7次,并且-Xss19m也不总是足够的,但是-Xss20m已经足够了(100次全部100次)。 垃圾收集,JIT踢,或其他事情导致这种不确定的行为?

在StackOverflowError打印的堆栈跟踪(可能还有其他例外情况)只显示运行时堆栈的最新的1024个元素。 下面的答案演示了如何计算到达的确切深度(可能比1024大很多)。

许多回应者指出,考虑替代的,相同algorithm的较less堆栈实现是一个好的和安全的编码实践。 一般来说,可以将一组recursion函数转换为迭代函数(使用例如Stack对象,而不是在运行时栈上填充)。 对于这个特定的factfunction,转换它是相当容易的。 我的迭代版本如下所示:

public class TTIterative { public static long fact(int n) { if (n < 2) return 1; if (n > 65) return 0; // Enough powers of 2 in the product to make it (long)0. long f = 2; for (int i = 3; i <= n; ++i) { f *= i; } return f; } public static void main(String[] args) { System.out.println(fact(1 << 15)); } }

仅供参考,正如上面的迭代解决scheme所示, fact函数无法计算65以上(实际上,甚至高于20)的确切因子数,因为Java内置typeslong会溢出。 重构的fact所以它会返回一个BigInteger而不是long也会产生大input的确切结果。

嗯…它适用于我和远远less于999MB的堆栈:

> java -Xss4m Test 0

(Windows JDK 7,构build17.0-b05客户端VM和Linux JDK 6 – 与您发布的版本相同)

我假设你计算堆栈跟踪中的循环线的“深度1024”? 显然,Throwable中的堆栈跟踪数组长度似乎被限制为1024,请尝试以下程序:

public class Test { public static void main(String[] args) { try { System.out.println(fact(1 << 15)); } catch (StackOverflowError e) { System.err.println(“true recursion level was “+level); System.err.println(“reported recursion level was “+e.getStackTrace().length); } } private static int level = 0; public static long fact(int n) { level++; return n < 2 ? n : n * fact(n – 1); } }

如果你想玩线程堆栈大小,你需要看看热点JVM上的-Xss选项。 在非热点虚拟机上可能有些不同,因为到JVM的-X参数是特定于分布的,IIRC。

在热点上,如果你想把大小设置为16兆,这看起来像java -Xss16M 。

inputjava -X -help如果你想查看所有可以传入的特定于分发的JVM参数。我不确定这是否和其他JVM一样,但是它打印所有的热点特定参数。

对于它的价值 – 我会build议限制你在Java中使用recursion方法。 在优化它们时不是太好,因为JVM不支持尾recursion(请参阅JVM是否阻止尾调用优化? )。 尝试重构上面的因子代码,以使用while循环而不是recursion方法调用。

控制进程内堆栈大小的唯一方法是启动一个新的线程。 但是你也可以用-Xss参数创build一个自调用的子java进程。

public class TT { private static int level = 0; public static long fact(int n) { level++; return n < 2 ? n : n * fact(n – 1); } public static void main(String[] args) throws InterruptedException { Thread t = new Thread(null, null, “TT”, 1000000) { @Override public void run() { try { level = 0; System.out.println(fact(1 << 15)); } catch (StackOverflowError e) { System.err.println(“true recursion level was ” + level); System.err.println(“reported recursion level was ” + e.getStackTrace().length); } } }; t.start(); t.join(); try { level = 0; System.out.println(fact(1 << 15)); } catch (StackOverflowError e) { System.err.println(“true recursion level was ” + level); System.err.println(“reported recursion level was ” + e.getStackTrace().length); } } }

因为你急于避免一切合理的方法,所以很难给出一个合理的解决scheme。 重构一行代码是可行的解决scheme。

注意:使用-Xss设置每个线程的堆栈大小,这是一个非常糟糕的主意。

另一种方法是通过字节码操作来更改代码,如下所示:

public static long fact(int n) { return n < 2 ? n : n > 127 ? 0 : n * fact(n – 1); }

因为n> 127的每个答案都是0.这样可以避免更改源代码。

添加此选项

–driver-java-options -Xss512m

到你的spark-submit命令将解决这个问题。

奇怪的! 你说你想要产生1 << 15深度 ???的recursion !

我build议不要尝试它。 堆栈的大小将是2^15 * sizeof(stack-frame) 。 我不知道堆栈大小是多less,但2 ^ 15是32.768。 呃,如果它在1024(2 ^ 10)的时候停下来的话,你将不得不把它做成2 ^ 5倍,比你的实际设置大32倍。

其他海报已经指出如何增加记忆,你可以记忆电话。 我build议,对于许多应用程序,你可以使用斯特林公式近似大n! 几乎没有内存占用。

在这篇文章中,有一些分析function和代码:

我做了Anagram excersize ,这就像Count Change问题,但有5万面值(硬币)。 我不确定它可以迭代完成 ,我不在乎。 我只知道-xss选项没有任何作用 – 我总是在1024个堆栈帧之后失败(可能是scala没有把工作交给java或printStackTrace限制,我不知道)。 无论如何,这是不好的select。 你不希望所有的线程在应用程序是可怕的。 但是,我做了一些新的线程(堆栈大小)的实验。 这确实有效,

def measureStackDepth(ss: Long): Long = { var depth: Long = 0 val thread: Thread = new Thread(null, new Runnable() { override def run() { try { def sum(n: Long): Long = {depth += 1; if (n== 0) 0 else sum(n-1) + 1} println(“fact = ” + sum(ss * 10)) } catch { case e: StackOverflowError => // eat the exception, that is expected } } }, “deep stack for money exchange”, ss) thread.start() thread.join() depth } //> measureStackDepth: (ss: Long)Long for (ss measureStackDepth((scala.math.pow (10, ss)).toLong) ) //> fact = 10 //| (ss = 10^0 allows stack of size ,11) //| fact = 100 //| (ss = 10^1 allows stack of size ,101) //| fact = 1000 //| (ss = 10^2 allows stack of size ,1001) //| fact = 10000 //| (ss = 10^3 allows stack of size ,10001) //| (ss = 10^4 allows stack of size ,1336) //| (ss = 10^5 allows stack of size ,5456) //| (ss = 10^6 allows stack of size ,62736) //| (ss = 10^7 allows stack of size ,623876) //| (ss = 10^8 allows stack of size ,6247732) //| (ss = 10^9 allows stack of size ,62498160)

您会发现堆栈可以以指数级更多的堆栈分配给线程,从而成倍地增长。

试试jvm参数:-Xmx128m

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/156364.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python numpy矩阵转置_python转制

    python numpy矩阵转置_python转制题目难度:★☆☆☆☆类型:几何、二维数组、数学给定一个矩阵A,返回A的转置矩阵。矩阵的转置是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引。示例示例1输入:[[1,2,3],[4,5,6],[7,8,9]]输出:[[1,4,7],[2,5,8],[3,6,9]]示例2输入:[[1,2,3],[4,5,6]]输出:[[1,4],[2,5],[3,6]]提示1…

    2022年11月1日
  • web前端设计与开发期末作品: 服装主题网页设计——女装下拉菜单带特效 (11页) HTML+CSS+JavaScript 网页设计期末作业个人主页…[通俗易懂]

    web前端设计与开发期末作品: 服装主题网页设计——女装下拉菜单带特效 (11页) HTML+CSS+JavaScript 网页设计期末作业个人主页…[通俗易懂]常见网页设计作业题材有​​个人、美食、公司、学校、旅游、电商、宠物、电器、茶叶、家居、酒店、舞蹈、动漫、明星、服装、体育、化妆品、物流、环保、书籍、婚纱、军事、游戏、节日、戒烟、电影、摄影、文化、家乡、鲜花、礼品、汽车、其他​​等网页设计题目,​​A…

    2022年9月3日
  • 使用PHP password_hash()加密,再也不怕被拖库了

    使用PHP password_hash()加密,再也不怕被拖库了

    2022年2月12日
  • CTK Plugin Framework简介

    CTK Plugin Framework简介CTKPluginFramework简介 框架简介 1.1、简介CTKPluginFramework设计参考了OSGi(OpenServiceGatewayInitiative,开放服务网关协议)(Java的动态组件系统),并提供了一种能让应用程序(动态地)由许多不同的可重用组件组成的开发模型,允许通过服务进行通信。OSGi规范的核心部分是一个框架,核心框架定义了应用程序的生命周期模式和服务注册。基于OSGI核心框架定义了大量的OSGi服务:日志、配置管理、HTTP(运行se

    2022年6月4日
  • W3C标准是_关于w3c标准下列说法错误的是

    W3C标准是_关于w3c标准下列说法错误的是W3C简介什么是W3C?万维网联盟(WorldWideWebConsortium)创建于1994年10月工作是对web进行标准化创建并维护WWW标准使用W3C的目的?为了让任何人在任何时间、任何地点、通过任何设备访问web内容。作为用户和浏览器制造商之间的中间层,要想办法满足下游的用户和上游不同浏览器看到的是同样的内容,让页面、程序能支持所有的浏览器,能够满足尽可能多的用户标准内容1、DOC…

    2022年9月17日
  • react路由原理解析[通俗易懂]

    react路由原理解析[通俗易懂]原理:在dom渲染完成之后,给window添加  “hashchange”事件监听页面hash的变化,并且在state属性之中添加了route属性,代表当前页面的路由。 1、当点击连接 页面hash改变时,触发绑定在window上的  hashchange事件, 2、在hashchange事件中改变组件的state中的route属性,(react组件的state属性改变时

    2022年5月24日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号