CS 3330: Lab 10: Memory

This page does not represent the most current semester of this course; it is present merely as an archive.

This lab has several activities. I suggest you

  1. fill in a few rows of each table in activity 1
  2. do all of activity 2
  3. spend the remainder of your time on activity 3.

My goal is to help you think about the material; how you get the answers is up to you. As long as you don't steal material from someone without their permission, any approach is fair game.

Activity 1: Multi-level Page Tables

Most memory systems use a page size that can fit one page table.

Assume that a page table entry is the same size as an address. Fill in the tables below to explore the resulting number of page tables for different page sizes. You may use K to mean *1024 and M to mean *1024*1024.

Assume we have 32-bit (4 byte) addresses and fill out the rest of the following table (note the jump between 16K and 128K):

Page size Entries per page table Page number bits Levels of page table needed Perfect fit?
1K
explanation
256
1K ÷ 4 bytes
8
lg(1K) − lg(4)
3
⌈(32 − 10) / 8⌉
No
22 % 8 ≠ 0
2K
4K 1024 10 2 Yes
8K
16K
128K
256K
512K

Assume we have 64-bit (8 byte) addresses and fill out the rest of the following table (note there is a jump between 64K and 512K):

Page size Entries per page table Page number bits Levels of page table needed Perfect fit?
4K
8K
16K
32K
64K
512K
1M 128K 17 3 No

Core i7 uses 48-bit address space stored in 64-bit addresses. If they are going to use 64 bits, why restrict them to a 48-bit address space?

Activity 2: Processes

Assume we have 32-bit virtual addresses and 4K pages. Assume also that every process has at least three pages of used memory: one page for shared libraries, one for data, and one for text. Assume that all of the the VPNs for each of these pages is distinct; only the top-level page table is shared.

  1. What is the minimum number of pages of memory a process needs, including all shared pages and page tables?

  2. Suppose your code uses a contiguous chunk of 32K data memory more than the minimum size. What is the minimum number of additional pages (beyond those counted in question 1) needed to store that data, including any new page tables?

  3. Suppose your code uses a contiguous chunk of 32K data memory more than the minimum size. What is the maximum number of additional pages (beyond those counted in question 1) needed to store that data, including any new page tables?

  4. Try running top -b -n 1 on the lab machine to get a dump of all of the processes running on the computer and how much memory each is using. The VIRT column is the allocated virtual memory; the RES is the amount of that which is stored in physical memory; the SHR is the amount that is stored on physical pages that are in two or more processes' virtual address spaces. All three of these are in kilobytes unless an m or g suffix is present.

    • Which process is using the most virtual memory?

      How much virtual memory is it using?

    • Which process is using the most physical memory?

      How much physical memory is it using?

    • Which process is using the most shared memory?

      How much shared memory is it using?

    • Which process has the largest number of non-resident pages?

      How much of its memory is swapped out to disk?

Activity 3: Code Concepts

Section 9.11 lists a variety of common memory bugs. Let's think a bit about each one.

Answer as many of these questions as you have time to think about carefully in lab. I'd rather see a few thoughtful answers than a lot of less thoughtful ones. Do your best within the time you have.

If you want to come back and answer them after lab, you may.

  1. Describe a case where dereferencing a bad pointer would not cause a segfault.

  2. C could have removed the possibility of uninitialized memory by only having calloc, not malloc. Why would that have been a bad idea?

  3. Buffer overflow is a source of many, many security vulnerabilities. They are all based on a method being passed a pointer into which it writes but not being given a maximum size for the writing.

    Is there a reason why there should be methods that accept destination pointers without sizes? If so, describe the reason; if not, write “c fails” instead.

  4. The book describes an error that arises because malloc(n*sizeof(int)) and malloc(n*sizeof(int*)) do the same thing in 32-bit code but different things in 64-bit code. This means that (poorly written) code cannot always work on both 32- and 64-bit machines.

    What is one other difficulty that might arise when switching code from 32- to 64-bit machines?

  5. Suppose you malloc(n*sizeof(int)) but access indices 0 through n instead of 0 through n-1. What evidence of that might you see when you run the program? List as many kinds of resulting behaviors as you can think of. You might want to actually make a C program that does this and see what happens.

  6. *size--; means *(size--); not (*size)--;. The book suggests we write it with parentheses no matter which one we intended so that the intent of the code is clear.

    What is a way of writing this that does not use parentheses but still has a clear intent? Write valid C code for the (*size)-- case in the box without using parentheses, assuming that size is an int *.

  7. In C, ptr += 1 changes the address pointed to be ptr by sizeof(*ptr). The book suggests some people expect it to change the address by 1 instead.

    Pick one of those two versions of adding to a pointer and defend why you think it is superior to the other one.

  8. The book describes a problem created by returning a pointer to a local variable. This fails because that part of stack memory will be re-used by later functions.

    If you try their code

    int * stackref() { int val; return &val; }

    you'll find that gcc complains “warning: function returns address of local variable”. Try to make code that either (a) returns the address of a local variable but confuses gcc so much that there is no warning. If you find such code, provide it below. If not, write “gcc wins” instead.

  9. In most implementations of C, free marks memory as unused but does not prevent its reuse by other code.

    If we changed malloc and free to deallocate the entire page of freed memory and never revisit that page, what is the maximum number of times we could call free without an error in a program running on a core i7 (which has a 48-bit virtual address space and 4K pages)?

    If each call to free took 1 micro-second, approximately how long would it take to call free that many times? Answer as a small integer followed by a period of time, like “3 seconds” or “38 centuries”

  10. Memory leaks are often cited as a reason for having a garbage collector. Java has a garbage collector; write a Java class Leaky with a static method void leak(int n) that has a memory leak like void leak(int n) { malloc(n); } does, or write “Java wins” if you cannot do so.

Copyright © 2015 by Luther Tychonievich. All rights reserved.
Last updated 2015-04-15 15:27 -0400