简体   繁体   中英

VS2012 OutOfMemoryException vs. VS2010 working w/o Exception

I had a project in Visual Studio 2010 that functioned properly. I transferred that project over to VS2012 and I am getting a OutOfMemoryException . I know why I am getting the exception, because I got the same one in 2010. The reason it occurred is because the application runs a genetic algorithm that produces several progeny where each child generated is composed of a large object (int array[500,200,7]). I reduced how many progeny got generated on each crossover and was able to get rid of the Exception, I also had to add in offspring.clear() , even though it is a local variable. In VS2012 it appears garbage collection is never picking up the offspring array that should be deallocated. I even added in GC.Collect() at the point where it should happen. I am confused why with the same code the program just continues to consume memory in VS2012.

    /// <summary>
    /// Runs the genetic algorithm
    /// </summary>
    public void RunAlgorithm()
    {
        for (int i = 0; i < progeny; i++)
            schedules.Add(new Schedule(true));

        schedules.Sort();
        best = schedules[0];

        while (best.unscheduled.Count > 15)
        {
            List<Scheduling.Schedule> offspring = GetOffspring();
            offspring.Sort();

            if (offspring[0].unscheduled.Count < best.unscheduled.Count)
                best = offspring[0];

            schedules.Clear();

            for (int s = 0; s < progeny; s++)
                schedules.Add(offspring[s]);

            offspring.Clear();
        }
    }

    public List<Scheduling.Schedule> GetOffspring()
    {
        List<Scheduling.Schedule> offspring = new List<Schedule>();

        int parentSize = (int)(schedules.Count * poolSizePcnt);

        for (int p1 = 0; p1 < parentSize; p1++)
        {
            for (int p2 = p1 + 1; p2 < parentSize; p2++)
            {
                Schedule[] children = Breed(schedules[p1], schedules[p2]);
                offspring.Add(children[0]);
                offspring.Add(children[1]);
            }
        }

        return offspring;
    }

    /// <summary>
    /// Returns an array of 2 children from the breeding of two parents with a single crossover point and potential mutation on the alleles.
    /// </summary>
    /// <param name="p1">Parent One</param>
    /// <param name="p2">Parent two</param>
    /// <returns></returns>
    public Schedule[] Breed(Schedule p1, Schedule p2)
    {
        Schedule c1 = new Schedule();
        c1.schedule = new int[p1.schedule.GetUpperBound(0) + 1, p1.schedule.GetUpperBound(1) + 1, p1.schedule.GetUpperBound(2) + 1];
        Schedule c2 = new Schedule();
        c2.schedule = new int[p1.schedule.GetUpperBound(0) + 1, p1.schedule.GetUpperBound(1) + 1, p1.schedule.GetUpperBound(2) + 1];

        //randomized crossover point from min to max
        int crssPnt = (int)(Schedule.rand.Next(min, max) / (10.0) * Schedule.courseIDdict.Count);

        for (int c = 0; c < crssPnt; c++)
        {
            int cID = Schedule.courseIDdict[c].id;
            //TODO: if cID is contained within a list, prevent from certain moves, e.g. to D
            for (int i = 1; i <= 6; i++)
            {
                int random = Schedule.rand.Next(0, mutationRate);

                if (p1.schedule[0, cID, i] >= 1)
                {
                    if (rand1 == random)//introduce mutation if the random number is hit
                        c1.schedule[0, cID, Schedule.rand.Next(1, 7)] = 1;
                    else
                        c1.schedule[0, cID, i] = 1;
                }

                if (p2.schedule[0, cID, i] >= 1)
                {
                    if (rand2 == random)//introduce mutation if the random number is hit
                        c2.schedule[0, cID, Schedule.rand.Next(1, 7)] = 1;
                    else
                        c2.schedule[0, cID, i] = 1;
                }
            }

        }

        for (int c = crssPnt; c < Schedule.courseIDdict.Count; c++)
        {
            int cID = Schedule.courseIDdict[c].id;

            for (int i = 1; i <= 6; i++)
            {
                int random = Schedule.rand.Next(0, mutationRate);

                if (p1.schedule[0, cID, i] >= 1)
                {
                    if (rand2 == random)//introduce mutation if the random number is hit
                        c2.schedule[0, cID, Schedule.rand.Next(1, 7)] = 1;
                    else
                        c2.schedule[0, cID, i] = 1;
                }


                if (p2.schedule[0, cID, i] >= 1)
                {
                    if (rand1 == random)//introduce mutation if the random number is hit
                        c1.schedule[0, cID, Schedule.rand.Next(1, 7)] = 1;
                    else
                        c1.schedule[0, cID, i] = 1;
                }
            }
        }

        c1.AddStudentsToClasses();
        c2.AddStudentsToClasses();

        return new[] { c1, c2 };
    }

There is an (any CPU) configuration in VS then there is a build target dropdown (in 2012) Project->Properties->Buid tab. Build Target often times will be set to x86 and you will see Out of Memory exceptions being thrown when there is still plenty of ram available. For instance you can have the any cpu configuration set and still be building for x86, via the build target option. This will cause Out of Memory Exceptions to occur when you hit 2GB of RAM usage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM