Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
内存使用本地变量而不是内联Java_Java_Memory Management_Garbage Collection - Fatal编程技术网

内存使用本地变量而不是内联Java

内存使用本地变量而不是内联Java,java,memory-management,garbage-collection,Java,Memory Management,Garbage Collection,另一个开发人员正在讨论代码的清晰性。他说使用局部变量会增加内存的使用。我们争辩说他们将被垃圾收集。如果日志记录语句调用一个命中db/其他外部资源的函数,这尤其是一个坏主意 但是下面的示例代码似乎支持他的说法——即使在使用jconsole调用GC之后,仍然可以看到类Worker使用的内存比Worked2少。你知道为什么吗 可用内存: 124629976-工人 124784720 package test; import java.util.concurrent.Executor; import j

另一个开发人员正在讨论代码的清晰性。他说使用局部变量会增加内存的使用。我们争辩说他们将被垃圾收集。如果日志记录语句调用一个命中db/其他外部资源的函数,这尤其是一个坏主意

但是下面的示例代码似乎支持他的说法——即使在使用jconsole调用GC之后,仍然可以看到类Worker使用的内存比Worked2少。你知道为什么吗

可用内存: 124629976-工人 124784720

package test;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class ObjectLife {

    public static void main(String[] args) {
        // simple multi thread to mimic web app
        // ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 3, 110, null, null);
        Executor pool = Executors.newFixedThreadPool(3);
        String type = "1";

        if (args.length > 0) {
            type = args[0];
        }
        Work w = null;
        if ("1".equals(type)) {
            w = new Worker();
        } else {
            w = new Worker2();
        }
        w.init(2);
        System.out.println("w type " + w.getClass().getName());
        Watch.me.print();
        pool.execute(w);
        pool.execute(Watch.me);

    }

}

class Watch implements Runnable {
    long prev = 0;
    static Watch me = new Watch();

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1100);
            } catch (InterruptedException e) {
                System.out.println("Intrpt thread " + e);
            }
            print();
        }
    }

    public void print() {
        Runtime r = Runtime.getRuntime();
        long free = r.freeMemory();
        System.out.println("Free " + free + ", delta " + (free - prev));
        System.out.println(", av " + r.maxMemory());
        prev = free;
    }

}

class Work implements Runnable {
    double val = 0;

    public void init(double val) {
        this.val = val;
    }

    void do2() {
    }

    @Override
    public void run() {
        int cnt = 0;
        while (++cnt < 175) {
            do2();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("Intrpt thread " + e);
            }
        }
        System.gc();
        System.out.println("Type, v3, : " + this.getClass().getName());
        Watch.me.print();

    }

}

class Worker extends Work {

    public void do2() {
        double local = ++val;
        double local2 = local * 2;
        System.out.println(" local " + local + " double " + local2);
    }
}

class Worker2 extends Work {

    public void do2() {
        System.out.println(" local " + ++val + " double " + (val * 2));

    }

}
封装测试;
导入java.util.concurrent.Executor;
导入java.util.concurrent.Executors;
公共阶级生活{
公共静态void main(字符串[]args){
//模拟web应用程序的简单多线程
//ThreadPoolExecutor池=新的ThreadPoolExecutor(5,3,110,null,null);
Executor pool=Executors.newFixedThreadPool(3);
字符串类型=“1”;
如果(args.length>0){
type=args[0];
}
工作w=零;
如果(“1”。等于(类型)){
w=新工人();
}否则{
w=新工人2();
}
w、 init(2);
System.out.println(“w类型”+w.getClass().getName());
Watch.me.print();
池。执行(w);
pool.execute(Watch.me);
}
}
类监视实现可运行{
长期预测=0;
静态手表我=新手表();
@凌驾
公开募捐{
while(true){
试一试{
睡眠(1100);
}捕捉(中断异常e){
System.out.println(“Intrpt线程”+e);
}
打印();
}
}
公开作废印刷品(){
Runtime r=Runtime.getRuntime();
long free=r.freemory();
System.out.println(“Free”+Free+,delta“+(Free-prev));
System.out.println(“,av”+r.maxMemory());
prev=免费;
}
}
类工作实现可运行{
双val=0;
公共void init(双val){
this.val=val;
}
void do2(){
}
@凌驾
公开募捐{
int-cnt=0;
而(++cnt<175){
do2();
试一试{
睡眠(100);
}捕捉(中断异常e){
System.out.println(“Intrpt线程”+e);
}
}
gc();
System.out.println(“Type,v3,:”+this.getClass().getName());
Watch.me.print();
}
}
班主任延长工作时间{
公开无效do2(){
双本地=++val;
双本地2=本地*2;
System.out.println(“本地”+local+“双精度”+local2);
}
}
类Worker2扩展了工作{
公开无效do2(){
System.out.println(“本地”++val+“双”+(val*2));
}
}
为什么类工作者会占用更多内存?即使在多次调用GC,然后断开Jconsole与进程的连接并让几秒钟通过之后?(每2秒检查并打印一次

可以看出,除了do2()方法外,代码与超级类work和worker是相同的

注: 我正在从jconsole连接,并在工作循环完成后调用GC。此GC调用确实有效。调用MX bean,可以看到可用内存下降

注意:我甚至注意到,如果我从我的应用程序上断开jconsole,那么等待4-5秒-可用内存会再次上升(我猜是连接到jconsole的头上)。这时我进行了测量。重点是我做了一些工作,等待JVM安定下来,然后测量

运行此程序并使用jconsole释放mem的视频

jconsole是一个免费的tol,其中JDK位于bin文件夹中

编辑类,这里增加了循环计数,现在无论使用哪个类,内存都是相同的

其他人能运行它吗

package test;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * Run with param 1 and 2 or change type to "2" and "1" Available memory changes, used jconsole to change force garbage collection.
 * 
 * See video https://www.youtube.com/watch?v=MadBdryX8uk
 */
public class ObjectLife {

    public static void main(String[] args) {
        // simple multi thread to mimic web app
        // ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 3, 110, null, null);
        Executor pool = Executors.newFixedThreadPool(3);
        String type = "1";

        if (args.length > 0) {
            type = args[0];
        }
        Work w = null;
        if ("1".equals(type)) {
            w = new Worker();
        } else {
            w = new Worker2();
        }
        w.init(2);
        System.out.println("w type " + w.getClass().getName());
        Watch.me.print();
        pool.execute(w);
        pool.execute(Watch.me);

    }

}

class Watch implements Runnable {
    long prev = 0;
    private int dieCnt = -1;
    static Watch me = new Watch();

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1100);
            } catch (InterruptedException e) {
                System.out.println("Intrpt thread " + e);
            }
            if (dieCnt > -1) {
                dieCnt--;

                if (dieCnt == 0) {
                    System.exit(0);
                }
            }
            print();
        }
    }

    public void print() {
        Runtime r = Runtime.getRuntime();
        long free = r.freeMemory();
        System.out.println("Pr v6 Free " + free + ", delta " + (free - prev) + ", av " + r.maxMemory());
        prev = free;
    }

    public void countDown() {
        dieCnt = 3;

    }

}

class Work implements Runnable {
    double val = 0;
    double val3 = 0;

    public void init(double val) {
        this.val = val;
    }

    void do2() {
    }

    @Override
    public void run() {
        int cnt = 0;
        while (++cnt < 475) {
            do2();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("Intrpt thread " + e);
            }
        }
        System.gc();
        System.out.println("Type : " + this.getClass().getName());
        Watch.me.print();
        System.out.println("oink");
        try {
            Thread.sleep(9100);
        } catch (InterruptedException e) {
            System.out.println("Intrpt thread " + e);
        }
        Watch.me.countDown();

    }

}

class Worker extends Work {

    public void do2() {
        double local = ++val;
        double local2 = local * 2;
        System.out.println(" local " + local + " double " + local2);
        val3 = local2 + 1;
    }
}

class Worker2 extends Work {

    public void do2() {
        System.out.println(" local " + ++val + " double " + (val * 2));
        val3 = (val * 2) + 1;

    }

}
封装测试;
导入java.util.concurrent.Executor;
导入java.util.concurrent.Executors;
/**
*使用参数1和2运行,或将类型更改为“2”和“1”可用内存更改,使用jconsole更改强制垃圾收集。
* 
*看视频https://www.youtube.com/watch?v=MadBdryX8uk
*/
公共阶级生活{
公共静态void main(字符串[]args){
//模拟web应用程序的简单多线程
//ThreadPoolExecutor池=新的ThreadPoolExecutor(5,3,110,null,null);
Executor pool=Executors.newFixedThreadPool(3);
字符串类型=“1”;
如果(args.length>0){
type=args[0];
}
工作w=零;
如果(“1”。等于(类型)){
w=新工人();
}否则{
w=新工人2();
}
w、 init(2);
System.out.println(“w类型”+w.getClass().getName());
Watch.me.print();
池。执行(w);
pool.execute(Watch.me);
}
}
类监视实现可运行{
长期预测=0;
私有int dieCnt=-1;
静态手表我=新手表();
@凌驾
公开募捐{
while(true){
试一试{
睡眠(1100);
}捕捉(中断异常e){
System.out.println(“Intrpt线程”+e);
}
如果(dieCnt>-1){
二元--;
如果(dieCnt==0){
系统出口(0);
}
}
打印();
}
}
公开作废印刷品(){
Runtime r=Runtime.getRuntime();
long free=r.freemory();
System.out.println(“prv6 Free”+Free+”,delta“+(Free-prev)+”,av“+r.maxMemory());
prev=免费;
}
公共空间倒计时(){
dieCnt=3;
}
}
类工作实现可运行{
双val=0;
双val3=0;
公共void init(双val){
this.val=val;
}
void do2(){
}
@凌驾
公开募捐{
int-cnt=0;
而(++cnt<475){
do2();
试一试{
睡眠(100);