精华内容
下载资源
问答
  • java栈的最大深度

    2019-09-27 10:59:48
    某公司面试,总监大叔过来,问了图论及栈的最大深度,然后^_^ 一直记着,今天搞一下 2. 代码 1 package com.goodfan.test; 2 3 public class JavaStackTest { 4 5 private int count = 0; 6 ...

    1. 概述

    某公司面试,总监大叔过来,问了图论及栈的最大深度,然后^_^

    一直记着,今天搞一下

     

    2. 代码

     1 package com.goodfan.test;
     2 
     3 public class JavaStackTest {
     4     
     5     private int count = 0;
     6     
     7     public void testStack(){
     8         count++;
     9         testStack();
    10     };
    11     
    12     public void test(){
    13         try {
    14             testStack();
    15         } catch (Throwable e) {
    16             System.out.println(e);
    17             System.out.println("stack height:"+count);
    18         }
    19     }
    20 
    21     public static void main(String[] args) {
    22         new JavaStackTest().test();
    23     }
    24 
    25 }

     

    控制台输出

    java.lang.StackOverflowError
    stack height:11421

    3. 总结

    3.1 java栈是java虚拟机的一个重要的组成部分,在栈里进行线程操作,存放方法参数等等。

    栈在初始化过后是有一定的大小的。

    栈的高度称为栈的深度,栈深度受栈帧大小影响。

    我们知道,在栈中存放局部变量,参数,运行中间结果等。

    3.2 增加参数(因为方法参数需要占用内存 所以栈可为方法本身占用的地方就减少了)

    public void testStack(int a, int b){
            count++;
            testStack(a,b);
        }

    控制台输出

    java.lang.StackOverflowError
    stack height:9654

    3.3 进一步,

    3.3.1 增加局部变量 数量

    复制代码
        public void testStack(int a, int b){
            int c =5;
            long d=4L;
            count++;
            testStack(a,b);
        }
    复制代码

    控制台输出

    java.lang.StackOverflowError
    stack height:7854

    3.3.2 增大变量值

    复制代码
        public void testStack(int a, int b){
            int c =5;
            long d=47777777777777777L;
            count++;
            testStack(a,b);
        }
    复制代码

    控制台输出

    java.lang.StackOverflowError
    stack height:7846

    由此可以看出,局部变量表内容越多,栈帧越大,栈深度越小。

    知道了栈深度,该怎么用呢?对JVM调优有什么用呢?

    当我们定义的方法参数和局部变量过多,字节过大,考虑到可能会导致栈深度多小,可能使程序出现错误。

    这个时候就需要手动的增加栈的深度,避免出错。

     

    3.4 调整jvm 栈大小

    C:\Users\rocky fang\Documents\mycode>java -Xss2m -cp "C:\Users\rocky fang\Documents\mycode" JavaStackTest
    java.lang.StackOverflowError
    stack height:23345

    C:\Users\rocky fang\Documents\mycode>java -Xss5m -cp "C:\Users\rocky fang\Documents\mycode" JavaStackTest
    java.lang.StackOverflowError
    stack height:93213

    C:\Users\rocky fang\Documents\mycode>java -Xss10m -cp "C:\Users\rocky fang\Documents\mycode" JavaStackTest
    java.lang.StackOverflowError
    stack height:423618

     

     

    转自:

    https://www.cnblogs.com/rocky-fang/p/8367018.html

    转载于:https://www.cnblogs.com/zt007/p/10431401.html

    展开全文
  • a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8 IADD -1 1 ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8 + a9 / a10 所以我认为java编译器在编译时可以按照上述步骤确定整个过程中操作数栈的最大深度,...
    public class Demo{
    
        public static void main(String[] args) {
            test();
        }
    
        public static void test( ) {
            int a1 = 100;
            int a2 = 200;
            int a3 = 300;
            int a4 = 400;
            int a5 = 500;
            int a6 = 600;
            int a7 = 700;
            int a8 = 800;
            int a9 = 900;
            int a10 = 1000;
            int h1 = ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8 + a9 / a10;
        }
    }
    

    idea 安装 ASM bytecode outline 之后,右键上面的类,选择 Show Bytecode Outline ,会生成 java 字节码的可视化代码,如下图红框中是代码

    "int h1 = ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8 + a9 / a10" 对应的字节码指令:

    下面表格列出了代码"int h1 = ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8 + a9 / a10" 的字节码指令执行过程中操作数栈的出栈、入栈情况,xLOAD 是压栈操作,将第几个变量压入栈顶,

    所以对导致栈的深度增加1,所以对栈深度的贡献为 +1,加减乘除指定是弹出栈顶的两个元素,并将计算的结果重新压入栈顶,所以对站深度的贡献= -2 + 1=-1

    指令 对栈深度的贡献 执行完后的栈深度 此时栈状态
    ILOAD 0 +1 a1
    ILOAD 1 +1 2

    a2

    a1

    IADD -1 1 a1 + a2
    ILOAD 2 +1 

    a3

    a1 + a2

    ILOAD 3 +1 3

    a4

    a3

    a1 + a2

    IADD -1 2

    a3 + a4

    a1 + a2

    ILOAD 4 +1 3

    a5

    a3 + a4

    a1 + a2

    ILOAD 5 +1 4

    a6

    a5

    a3 + a4

    a1 + a2

    ILOAD 6 +1 5

    a7

    a6

    a5

    a3 + a4

    a1 + a2

    IDIV -1 4

    a6 / a7

    a5

    a3 + a4

    a1 + a2

    IADD -1 3

    a5 + a6 / a7

    a3 + a4

    a1 + a2

    ISUB -1 2

    ( a3 + a4 ) - ( a5 + a6 / a7 )

    a1 + a2

    IMUL -1 1 ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) )
    ILOAD 7 +1 2

     a8

     ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) )

    ISUB -1 1 ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8
    ILOAD 8 +1 2

    a9

    ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8

    ILOAD 9   +1 3

     a10

     a9

    ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8

    IDIV -1 2

    a9 / a10

    ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8

    IADD -1 1 ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8 + a9 / a10

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    所以我认为java编译器在编译时可以按照上述步骤确定整个过程中操作数栈的最大深度,至少理论上是可行的。如果存在分支判断时,每个单独的分支的最大栈深度都可以确定,结果就取最大的那个就行了,比如

    boolean flag=true;
    if( flag ){
    	int h1 = ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8 + a9 / a10;//maxStackSize=5
    }else {
    	int h2 = ( a1 + ( a2 + ( a3 + ( a4 + ( a5 + ( a6 + ( a7 + ( a8 + ( a9 + a10 ) ) ) ) ) ) ) ) );//maxStackSize=5
    }

    这段代码的最大操作数栈深度为10,但是注意

    if( true ){
    	int h1 = ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8 + a9 / a10;//maxStackSize=5
    }else {
    	int h2 = ( a1 + ( a2 + ( a3 + ( a4 + ( a5 + ( a6 + ( a7 + ( a8 + ( a9 + a10 ) ) ) ) ) ) ) ) );//maxStackSize=5
    }

    这段代码的操作数栈最大深度是5,因为 true是常量,编译器检测到后直接把判断分支干掉了,相当于字节码里面只有 "int h1 = ( a1 + a2 ) * ( ( a3 + a4 ) - ( a5 + a6 / a7 ) ) - a8 + a9 / a10'这段代码 。

    可能有人会说你举得例子是最简单的情况,就是一个固定的算术公式,最大栈深度很好确定,但是如果是动态的复杂的情况呢?比如for 循环,因为循环的次数都是不确定的。

    貌似不太好确定最大深度吧?那我们就来分析一下吧!

    public static void test( ) {
    	int sum=0;
    	for(int i =0;i<10;i++){
    		sum+=i;
    	}
    }

    这段代码生成的字节码指令如下:

    public static test()V
       L0
        LINENUMBER 13 L0
        ICONST_0                ==>       int sum = 0;
        ISTORE 0
    
       L1
        LINENUMBER 14 L1
        ICONST_0                ==>       int i = 0;
        ISTORE 1
    
       L2
       FRAME APPEND [I I]
        ILOAD 1
        BIPUSH 10              ==>   if( i < 10 ) 不成立,跳转到 return 处,否则 按顺序执行到 L4 处
        IF_ICMPGE L3
    
       L4
        LINENUMBER 15 L4
        ILOAD 0
        ILOAD 1                ==>  sum += i;
        IADD
        ISTORE 0
    
       L5
        LINENUMBER 14 L5
        IINC 1 1                ==>  i++,然后跳转到 L2 处,继续执行 if( i < 10 ) 判断
        GOTO L2
    
       L3
        LINENUMBER 17 L3
       FRAME CHOP 1
        RETURN
    
       L6
        LOCALVARIABLE i I L2 L3 1
        LOCALVARIABLE sum I L1 L6 0
        MAXSTACK = 2
        MAXLOCALS = 2
    }

    显然 for 循环其实相当于多次执行了 if 分支判断,即相当于多个 if 分支,满足上述多分支判断情况,可以确定最大栈深度!

    展开全文
  • java 最大深度

    2019-09-24 07:40:27
    java 栈 最大深度 ...某公司面试,总监大叔过来,问了图论及栈的最大深度,然后^_^ 一直记着,今天搞一下 2. 代码 package com.goodfan.test; public class Java...

     

     

    1. 概述

    某公司面试,总监大叔过来,问了图论及栈的最大深度,然后^_^

    一直记着,今天搞一下

     

    2. 代码

    复制代码
    package com.goodfan.test;
    
    public class JavaStackTest {
        
        private int count = 0;
        
        public void testStack(){
            count++;
            testStack();
        };
        
        public void test(){
            try {
                testStack();
            } catch (Throwable e) {
                System.out.println(e);
                System.out.println("stack height:"+count);
            }
        }
    
        public static void main(String[] args) {
            new JavaStackTest().test();
        }
    
    }
    复制代码

    控制台输出

    java.lang.StackOverflowError
    stack height:11421

    3. 总结

    3.1 java栈是java虚拟机的一个重要的组成部分,在栈里进行线程操作,存放方法参数等等。

    栈在初始化过后是有一定的大小的。

    栈的高度称为栈的深度,栈深度受栈帧大小影响。

    我们知道,在栈中存放局部变量,参数,运行中间结果等。

    3.2 增加参数(因为方法参数需要占用内存 所以栈可为方法本身占用的地方就减少了)

    public void testStack(int a, int b){
            count++;
            testStack(a,b);
        }

    控制台输出

    java.lang.StackOverflowError
    stack height:9654

    3.3 进一步,

    3.3.1 增加局部变量 数量

    复制代码
        public void testStack(int a, int b){
            int c =5;
            long d=4L;
            count++;
            testStack(a,b);
        }
    复制代码

    控制台输出

    java.lang.StackOverflowError
    stack height:7854 

    3.3.2 增大变量值

    复制代码
        public void testStack(int a, int b){
            int c =5;
            long d=47777777777777777L;
            count++;
            testStack(a,b);
        }
    复制代码

    控制台输出

    java.lang.StackOverflowError
    stack height:7846

    由此可以看出,局部变量表内容越多,栈帧越大,栈深度越小。

    知道了栈深度,该怎么用呢?对JVM调优有什么用呢?

    当我们定义的方法参数和局部变量过多,字节过大,考虑到可能会导致栈深度多小,可能使程序出现错误。

    这个时候就需要手动的增加栈的深度,避免出错。

     

    3.4 调整jvm 栈大小

    C:\Users\rocky fang\Documents\mycode>java -Xss2m -cp "C:\Users\rocky fang\Documents\mycode" JavaStackTest
    java.lang.StackOverflowError
    stack height:23345

    C:\Users\rocky fang\Documents\mycode>java -Xss5m -cp "C:\Users\rocky fang\Documents\mycode" JavaStackTest
    java.lang.StackOverflowError
    stack height:93213

    C:\Users\rocky fang\Documents\mycode>java -Xss10m -cp "C:\Users\rocky fang\Documents\mycode" JavaStackTest
    java.lang.StackOverflowError
    stack height:423618

    posted on 2019-03-21 19:21 shoshana~ 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/shoshana-kong/p/10573875.html

    展开全文
  • 观察java中栈的最大递归深度

    千次阅读 2012-01-07 17:52:27
    无聊观察了一下,没有对jvm参数进行调整,直接用myeclipse进行跑application 9000附近 机器内存2g 附简单程序: public class StackSize { private int size = 1; public void stackLeak... public static

     无聊观察了一下,没有对jvm参数进行调整,直接用myeclipse进行跑application

    9000附近

    机器内存2g

    附简单程序:

    public class StackSize {
    
    	private int size = 1;
    	
    	public void stackLeak(){
    		size++;
    		stackLeak();
    	}
    	public static void main(String[]args) throws Throwable{
    		StackSize gg = new StackSize();
    		try{
    			gg.stackLeak();
    		}catch(Throwable e){
    			System.out.println(gg.size);
    			throw e;
    			//e.printStackTrace();
    		}
    	}
    }


     

    展开全文
  • 一般代码或许不会涉及最大参数长度和最大栈深度,但某些特殊场合,检测这两个参数还是有必要。例如:用递归计算斐波那契数列第n个值,不了解最大栈深度,难免显得肤浅。又例如:将一串charCode转成String,不...
  • 请实现一个函数,可以获取列表嵌套列表的最大深度为多少。 输入描述: 输入参数为字符串型的 n维数组,列表的每一项值为数组 或 int型数字。数组内的数组,每一项值,也可以是数组 或 int型数字。 输出描述: int型...
  • 一般代码也许不会涉及最大參数长度和最大栈深度,但某些特殊场合,检測这两个參数还是有必要。比如:用递归计算斐波那契数列第n个值,不了解最大栈深度,难免显得肤浅。又比如:将一串charCode转成String,不...
  • 起因是严蔚敏版数据结构第277页的一句话:“如果改写算法10.7,在一趟排序之后比较分割所得两部分的长度,且先对长度短的子序列中的记录进行快速排序,则栈的最大深度可降为O(logn)。”(注:这里的logn是log2n的...
  • 1. 问题描述: 如果字符串满足一下条件之一,则可以称之为 有效括号字符串(valid parentheses string,可以简写为 ...类似地,可以定义任何有效括号字符串S 嵌套深度 depth(S): depth("") = 0 depth(A + B) = ..
  • 最大的岛屿面积。 输入输出: 输入: [[0,0,1,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,1,1,0,1,0,0,0,0,0,0,0,0], [0,1,0,0,1,1,0,0,1,0,1,0,0], [0,1,0,0,1,1,0,0,1,1,...
  • Java最大栈深度有多大

    千次阅读 2020-02-15 16:25:40
    无论你是跟同事、同学、上下级、同行、或者面试官讨论技术问题时候,很容易卷入JVM大型撕逼现场。为了能够让大家从大型撕逼现场中脱颖而出,最近我苦思冥想如何把知识点尽可能呈现容易理解,方便记忆。于是就...
  • 题解:使用一个栈,记录栈的最大深度 当遇到左括号入栈,遇到右括号时,判断当前最大深度是否是小于栈大小,若小于,则另max=st.size(),然后将左括号出栈。最后返回max大小。 public static int maxDepth(String ...
  • 对于栈深度的定义: ...栈深度是在一次计算中会用到的空间的最大值。 对于快速排序,假设数组参数的传递是用指针来指示的,所以每次过程调用只需要O(1)的空间。 去除尾递归的快速排序伪代码如下:TA
  • 给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远...返回它的最大深度 3 。 ——题目难度:简单 DFS递归版 解题 -dfs递归版 代码 /** * Definition for a binary tree node. * struct Tree...
  • 求二叉树的最大深度

    2020-02-01 18:07:58
    求二叉树的最大深度 递归法(深度优先) int maxDepth(TreeNode* root) { if(root==nullptr) return 0; int l = maxDepth(root->left)+1; int r = maxDepth(root->right)+1; return l>r?l:r; ...
  • 深度优先搜索(DFS)

    千次阅读 2020-02-13 23:00:44
    与 BFS 类似,深度优先搜索(DFS)是用于在树/图中遍历/搜索另一种重要算法。也可以在更抽象场景中使用。 正如树遍历中所提到,我们可以用 DFS 进行 前序遍历,中序遍历 和 后序遍历。在这三个遍历顺序中有...
  • 文章目录1 二叉树的最大深度1.1 DFS-递归1.2 DFS-循环(实现)1.3 BFS-循环(队列实现)2 二叉树的最小深度2.1 DFS递归2.2 DFS 循环2.3 BFS 104.二叉树的最大深度 111.二叉树的最小深度 1 二叉树的最大深度 给定...
  • 如果我们知道了根节点的 左子树,右子树的 最大深度 l,r,那么该二叉树的最大深度为 max(l,r) + 1 而左子树,右子树的最大深度,同样也可以通过上述的方式计算出来。 递归在访问到空节点时 退出。
  • 给定一个包含了一些 0 和 1非空二维数组grid, 一个岛屿是...找到给定二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。) 示例 1: [[0,0,1,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,...
  • 二叉树的最大深度

    2020-03-21 20:15:54
    刚开始拿到这道题的时候我就想可以使用遍历的方法访问每个节点,后来从leetcode上获得可以使用迭代的方法,通过更新栈的方法逐步更新栈中的数据,每次获得一个新的数据 就将原来 的 数据弹出,这里 我采用java实现 ...
  • 给定一个二叉树,找出其最大深度。 二叉树深度为根节点到最远叶子节点最长路径上节点数。 自己思路: 终于自己写出了一道题,这道题确实很简单,使用一个简单递归就可以了,利用深度优先搜索或者广度搜索...
  • 题目 给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 解答 ...每个结点的最大深度 = max(左子树的最大深度...
  • 利用实现二叉树的非递归遍历(前序、中序、后序和层序),获取二叉树的叶子节点个数、二叉树的深度、两个结点的最近公共祖先以及二叉树结点的最大距离
  • 题意: 给定一个二叉树,找出其最大深度(二叉树的深度为根节点到最远叶子节点的最长路径上的节点数)...返回它的最大深度 3 。 方法一: 利用一个stack()放置从树中遍历出来的节点,设置一个指针(gp),遇到每...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 681
精华内容 272
关键字:

栈的最大深度